coin-or / CppAD

A C++ Algorithmic Differentiation Package: Home Page
https://cppad.readthedocs.io
Other
446 stars 94 forks source link

Discrete coefficient sets for polynomial vary as a function of dependent variable #163

Closed a-jp closed 1 year ago

a-jp commented 1 year ago

Hi, Using CppAD along with its interface to IpOpt. I have the following (which can't be changed, in the sense the polynomial must have discrete ranges for its coefficients):

x is an AD<double> and is a variable being solved for by IPopt. The polynomial is: poly(x) = m1*x^2 + m2*x + m3

The result of poly(x) feeds directly into the objective, and in some cases constraints also.

m1, m2, m3 are just coefficients, doubles, but their choice depends on the value of x and in particular whether x falls within a certain range, as follows:

if x >= x1 and x < x2: then m1 = a1, m2 = a2, m3 = a3

else if x >= x2 and x < x3: then m1 = b1, m2 = b2, m3 = b3

else if x >= x3 and x <= x4: then m1 = c1, m2 = c2, m3 = c3

the coefficients, a1, b1, c1 etc are all known, do not depend on the model and are known before IpOpt starts, and the form of the polynomial does not change, but which coefficients to use does change depending on the value of x. How should I code up these if tests to work properly with CppAD and IPopt?

I've noticed odd behaviour with retape=true, which when true prevents me using the sparsity options, and even with the sparsity options false, retape being true or false sometimes give different results. In general I'm unsure how to approach this and have had multiple attempts.

Any help including any suggested code would be really appreciated.

bradbell commented 1 year ago

You should use conditional expressios for the coefficients m1, m2, m3. Then you should not have to re-tape. See https://coin-or.github.io/CppAD/doc/condexp.htm

Please report back if this solves your problem.

a-jp commented 1 year ago

Hi, yes I worked with those. But this problem has a lower and upper bound to satisfy simultaneously, both of them need to be true before m1 = a1. How can I use a conditional expression when it can only be written for the lower or the upper bound, but not both at the same time? Can you provide an example? Thanks

bradbell commented 1 year ago

You can nest conditional expressions so that if condition 1 is true and condition 2 is true then the value is non-zero, else the value is zero.

Then sum the result of all your different cases.

a-jp commented 1 year ago

Ok, by nest you mean use one inside another conditional expression as one of that one's arguments?

bradbell commented 1 year ago

For example, suppose we want if (x >= x1 and x < x2) then m1 = a1 otherwise 0

zero  = 0.0
tmp   = CondExpGe(x, x1,  a1, zero)
m1    = CondExpLt(x, x2, tmp, zero)
a-jp commented 1 year ago

Ok thanks I'll try this.

a-jp commented 1 year ago

Trying the above. I'll keep working on it, I must have something wrong, but any clue to help why I now get this error in debug:

cppad-20220000.4 error from unknown source Error detected by false result for size_t(arg[0]) < static_cast (CompareNe) at line 834 in the file ./debug/cppad/install/include/cppad/local/op/cond_op.hpp

I should add that I make no use of CompareNe

bradbell commented 1 year ago

Looking at the code referenced above, it is making sure that the comparison is not an Ne.

Error from an unknown source could be anything from a bug you your code to a bug in the CppAD code. In a case like this, the best thing is to simplify your code until you are certain it does not have a bug and then report the case as a CppAD issue (with the simple example).

You could try using the current CppAD master branch from github and see if the error still occurs ?

a-jp commented 1 year ago

So it seems sensitive on whether I get the above error, to whether how many of the expression that are/should be zero are chained to each other, reducing the chaining stops the above error, albeit the code is not functionally correct. I can also get the following error depending on how many results from CondExp I chain to each other as a final returned result...

cppad-20220000.4 error from unknown source Error detected by false result for arg[arg[4] ] == arg[4] at line 233 in the file ./debug/cppad/install/include/cppad/local/play/sequential_iterator.hpp

If i go back to my old code these errors all stop.

a-jp commented 1 year ago

Looking at the code referenced above, it is making sure that the comparison is not an Ne.

Ok, but I only use Gt, Ge, Lt, Le??

a-jp commented 1 year ago

Putting retape back to true, just to see, and with the new code, errors go away...not sure what that tells me?

bradbell commented 1 year ago

How many lines of code do you need to get the error ?

bradbell commented 1 year ago

@a-jp I will be away from the internet for a while and will look for you simple example that demonstrates the problem when I get back.

a-jp commented 1 year ago

Thanks for the heads up. Appreciate it

bradbell commented 1 year ago

@a-jp Is this still an issue for you ?

a-jp commented 1 year ago

I don't think so. Thanks