Error in definition of binary variable in CPLEX ](https://i.stack.imgur.com/HKHoc.jpg)
the entries of x is either zero or any positive floating point number. For every nonzero value of x, corresponding entry of y is 1 otherwise its entry is zero. This code is written in CPLEX. But the error is getting due to binary nature of y. The code is in attached image.
Thankyou in advance for any help.!](https://i.stack.imgur.com/wM2tP.jpg)
For a binary the right keyword is boolean:
dvar boolean x;
subject to
{
x==0;
}
works fine
Related
I implemented the powf(float x, float y) math function. This function is a binary floating point operation. I need to test it for correctness,but the test can't iterate over all floating point. what should I do.
Consider 2 questions:
How do I test binary floating point math functions?
Break FP values into groups:
Largest set: Normal values including +/- values near 1.0 and near the extremes as well as randomly selected ones.
Subnormals
Zeros: +0.0, -0.0
NANs
Use at least combinations of 100,000s+ sample values from the first set (including +/-min, +/-1.0, +/-max), 1,000s from the second set (including +/-min, +/-max) and -0.0, +0.0, -NAN, +NAN.
Additional tests for the function's edge cases.
How do I test powf()?
How: Test powf() against pow() for result correctness.
Values to test against: powf() has many concerns.
*pow(x,y) functions are notoriously difficult to code well. The error in little sub-calculations errors propagate to large final errors.
*pow() includes expected integral results with integral value arguments. E.g. pow(2, y) is expected to be exact for all in range results. pow(10, y) is expected to be within 0.5 unit in the last place for all y in range.
*pow() includes expected integer results with negative x.
There is little need to test every x, y combination. Consider every x < 0, y non-whole number value leads to a NAN.
z = powf(x,y) readily underflows to 0.0. Testing of x, y, values near a result of z == 0 needs some attention.
z = powf(x,y) readily overflows to ∞. Testing of x, y, values near a result of z == FMT_MAX needs more attention as a slight error result in FLT_MAX vs. INF. Since overflow is so rampant with powf(x,y), this reduces the numbers of combinations needed as it is the edge that is important and larger values need light testing.
I had trouble solving a simple problem with gurobi:
e^x+x=lnP
x=1
In Gurobipy,it transforms into this form:
x+y=temp
y=e^x
lnP=temp
x=1
The result is here:
Variable X
x 1
P 749.103
y 2.71828
Temp 3.71828
The code is as follows:
from gurobipy import *
model = Model('Antoine')
P = model.addVar(vtype=GRB.CONTINUOUS, name='P',lb=0)
x = model.addVar(vtype=GRB.CONTINUOUS, name='x',lb=0)
y = model.addVar(vtype=GRB.CONTINUOUS, name='y',lb=-GRB.INFINITY)
temp = model.addVar(vtype=GRB.CONTINUOUS, name='Temp1',lb=-GRB.INFINITY)
model.addConstr(x == 1)
model.addGenConstrExp(x,y)
model.addConstr(x+y == temp)
model.addGenConstrLog(P,temp)
model.setObjective(P, GRB.MINIMIZE)
model.write("test.lp")
model.optimize()
I don't know why the result of P is wrong
Gurobi represents nonlinear functions by piecewise linear approximations. When I solve the original model on my computer using Gurobi Optimizer 9.5.2, I get the following warning:
Warning: max constraint violation (2.9006e+00) exceeds tolerance
Warning: max general constraint violation (2.9006e+00) exceeds tolerance
Piecewise linearization of function constraints often causes big violation.
Try to adjust the settings of the related parameters, such as FuncPieces.
This means the default automatic linearization is not sufficiently accurate for this model. As suggested in the warning message, adjust the FuncPieces parameter to get a more accurate representation for this model. For example, with model.Params.FuncPieces=-1 on my computer, I get this more accurate result:
Variable X
-------------------------
P 41.29
x 1
y 2.71828
Temp1 3.71828
I am calling cblas_sgemm using the following parameters:
order: CblasRowMajor
transA, transB: either CblasTrans or CblasNoTrans
M: the number of rows (height) of the matrix op(A) and of the matrix C
N: the number of columns (width) of the matrix op(B) and of the matrix C
K: the number of columns (width) of the matrix op(A) and the number of rows (height) of the matrix op(B)
alpha: scalar
A: pointer to matrix A
LDA: When transA = CblasNoTrans then LDA = M, otherwise LDA = K
B: pointer to matrix B
LDB: when transB = CblasNoTrans then LDB = K, otherwise LDB = N
beta: scalar
C: pointer to matrix C (bias on entry and the result on exit)
LDC = M
where, op(M) = M if transM is CblasNoTrans, and Transpose(M) otherwise
The parameters are correct (according to the documentation) but I am getting am error:
"** On entry to SGEMM, parameter number X had an illegal value" - How do I fix this error?
TL;DR
When using: CblasRowMajor
Keep M,N,K setting as listed above.
Flip Transpose value when computing LDA,LDB, and set LDC = N
Details:
I ran into this problem using multiplication with Transpose and could not find a detailed answer that answers my problem. I write this Q/A in hope it will be useful for others.
The root problem, as others have noted, is that cblas is a wrapper over BLAS, which is written in FORTRAN that does not have an order parameter and expect column major matrix representation. The available documentation (usually) is the BLAS documentation - which I used above in the question.
However, While M,N,and K are logical values (the width/height of matrix regardless of its representation) the leading dimensions (LDA, LDB, LDC) are not. Therefore the computation of M,N, and K should stay the same when using CblasRowMajor. However, the transpose of op(A), op(B) and C, should be use when computing LDA, LDB, and LDC.
If CblasColMajor is used then it is the same representation as Fortran and the parameter setting shown in the question is the correct one.
Also note that when you get and error in parameter X, X is shifted by 1 because the error originated in BLAS that does not have an order parameter.
I am using Z3 to solve an optimization problem. the objective is to maximize the value of a variable, call it X, X is the summation of:
X = x1+x2+x3+x4+...+xi
each term form x1 to xi represents a non-linear equation. So, I can't use the optimization APIs. Instead, I first get a value for X and begin a loop. in each iteration, I add another constraint to get X greater than the previous generated X value.
I noticed that the first value is the maximum value and in each time the program enters the loop, I wait for a long long time to get another greater value but it never generates new values. I changed the values of the input and this happens in each time.
is that a coincidence? or Is the Z3 designed such that it generates the max. values for such formulas?
Z3 doesn't really do non-linear optimization: Depending on the heuristics it uses, it may or may not give you an answer. (Most likely it'll either say unknown or run forever.) The hack you're implementing is likely the best you can get if you have truly non-linear constraints and you're not getting any mileage from z3 out-of-the-box. Another option would be to use strategies/tactics to guide the solver, but that is not for the faint of the heart and is not guaranteed to work.
See here for the original optimization z3 paper, which clearly states it is for the linear fragment: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/nbjorner-nuz.pdf
For a good read on strategies in z3, see: http://www.cs.tau.ac.il/~msagiv/courses/asv/z3py/strategies-examples.htm
I am converting a FORTRAN code that maintains at least 16 decimal precision.
I am facing a problem of dividing by zero in VBA excel, but If I try the code below on this online compiler, I do not get a zero.
Any help is appreciated. Thanks in advance.
This is the fortran Code
program sum
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
x = 3.14159265358979
y = 1.24325643454325
z = (x*y)/dtan(0.0D0)
print *, datan(.04D0*z)
end program sum
This is the VBA Code
Public Function dosomething()
Dim X As Double
Dim Y As Double
Dim Z As Double
X = 3.14159265358979
Y = 1.24325643454325
Z = (X * Y) / Tan(0#)
End Function
Without going into too many details, Fortran can support real values (floats) of +/-Infinity and NaN, depending on how the value is calculated. For example, your original post contained two uninitialized variables which you then used to calculate (v1 * v2)/dtan(0.0d0). Since uninitialized vars are often (but not always) set to 0, this calculation becomes 0.0/0.0, which is mathematically undefined and the result is NaN.1
Now, if the numerator is positive, z=(x*y)/dtan(0.0D0) results in z=Infinity, regardless of what x and y are. If your system cannnot represent Infinity, then it uses "a very large number". That is evidently the case with VBA.
Finally, you calculate datan(.04D0*z). Mathematically, this is arctangent(Infinity)=PI/2. And again, the correctly computed Fortran results match this, returning a double-precision value of 1.57079632679490.2
Now, I don't know much about VBA, but it does not seem to support +/-Infinity or NaN. If a "very large number" results in significant error compared to what you are expecting in your final result, then it appears there are workarounds as described at this SO question.
1 Note that in Fortran with double precision you should get dtan(0.0d0) = 0.000000000000000E+000.
2
In order to maintain double-precision in the Fortran x and y variables, you must append d0. Otherwise they will become single-precision values by default and store only the first 7 sig figs from your original assignment, and it's up to the compiler what the remaining digits in the double-precision value take (usually just garbage).
Z = (X * Y) / Tan(0#)
The type hint on the 0 literal is superfluous, Tan function takes a Double and returns a Double. But Tan(0) returns 0, so you are dividing by 0.
Seems your online Fortran compiler is doing something funky.
it should not be zero tho, it should be tan(1E-16)
No. That's mathematically wrong, VBA is doing it right. If you need your VBA code to be just as broken as that Fortran, then you need to handle the situation explicitly:
Z = (X * Y) / Tan(1E-16)
But just know that is mathematically wrong. I've not idea how the Fortran code manages to output 1.5707963267948966. This VBA code outputs 3.90580528128931E+16.