I need help to make a constraint that round a variable up: what math.ceil() function does. The problem is I'm using pyomo for an optimization model.
The constraint I made:
def Trucks(model,i):
return math.ceil(model.C[i])
model.trucks = Constraint(model.I, Trucks)
( model.I=RangeSet(n) )
I expected model.C rounded up
I got "Implicit conversion of Pyomo numeric value (C[1]) to float is disabled.
This error is often the result of using Pyomo components as arguments to
one of the Python built-in math module functions when defining
expressions. Avoid this error by using Pyomo-provided math functions or
explicitly resolving the numeric value using the Pyomo value() function."
ciel is a non-linear function that you cannot incorporate into a pyomo model. If the variable C should be an integer, just change the variable type to integer and it should work fine.
Related
Say I define the parameter pi = -acos(-1.0) and save it in a module. When I use this module in another program, is the value of pi computed from the function ACOS each time?
If that's the case, is it better to define pi = -3.1415.... to whatever precision I require?
If you have a named constant defined in a module then its value must be given by a constant expression. In a compile/execute module this constant expression will typically be evaluated when compiling the module itself, rather than when it is ultimately referenced.
Either way, there is no possibility for something using a module to affect the evaluation of the named constant's value in that module.
For the example of the question, ACOS(-1.0) is evaluated using whatever the default real kind is at the time of compiling. If this is changed to something like
module pidef
use, intrinsic :: iso_fortran_env, only : piprec => real64
implicit none
real(piprec), parameter :: pi = ACOS(-1.0_piprec)
end module
then the constant expression uses the value of piprec in scope at that point. Being a constant expression every value must be well-defined by then. It will not be the case that something like
program piuse
use, intrinsic :: iso_fortran_env, only : piprec => real32
use pidef
implicit none
end program
will somehow evaluate pi using real32. Equally there is no way to reference in the module's constant expression a variable defined globally later on, after the module is compiled.
No, parameters are calculated at compile time. The performance of the two methods should be identical.
Also, if you are wondering which of two options is faster, the answer is almost always "try it and see". If you care about your code running fast, you should use a code profiler to accurately time your code and work out what is slowing it down.
N.B. while the speed should be the same, there is the issue of precision. If you define pi using acos(-1.0) it will only be accurate to default single precision. If you want to define pi like this, you should use acos(-1.0_dp), where dp defines the floating-point precision you need.
I am using dlib library for c++ to perform box-constrained optimization of custom function:
dlib::find_min_box_constrained(dlib::bfgs_search_strategy(),
dlib::objective_delta_stop_strategy(DELTA),
m, dlib::derivative(m),
starting_point, MIN_CONS, MAX_CONS);
where m is the objective function, starting_point is column vector of the initial values of the variables, MIN_CONS is the minimal allowed value for each of the variable and MAX_CONS is the maximal allowed value.
This works fine, but now, I would like to add another constraint on the variables - I want them to sum to 1. I am able to do this using scipy.optimize.minimize in python3 (answered in this question). Is there any way to achieve this using dlib?
In Fortran, I always work with double precision, so I have been using specific functions like dble and dimag to get real and imaginary parts of complex variables. However, for other functions like sin, I no longer use dsin because the former returns a value of proper kind (i.e., sin is a generic function). The same seems to hold for complex variables. So my question is:
1) What are the most recommended generic functions for getting real and imaginary parts?
-- It seems that real(z), aimag(z), and conjg(z) return a proper kind always (via experiments with gfortran), i.e., if z is double precision, those functions return double precision. Is this guaranteed? Also, is the behavior dependent on the standard used by the compiler? (i.e., Fortran 77 vs 90 or later, particularly for real(z)?)
2) If I (nevertheless) want to use specific functions that receives only double precision arguments and always return double precision values, what are the specific functions?
-- I have been using dble(z) and dreal(z), dimag(z), dconjg(z) up to now, but some web pages say that they are vendor extensions (though commonly supported by many compilers).
I have read various pages but the information is rather confusing (i.e., it is not very clear what is the "standard" way), so I would appreciate any advice on the choice of such functions.
As background, what do we mean by kinds of real and complex variables? Of course, you know what is meant by the kind of a real object.
A complex object consists of a real and an imaginary part. If a complex object has a given kind then each component is a real of kind corresponding to the kind of the complex object.
That's a long way of saying, if
complex(kind=k) z
then KIND(z%re) and KIND(z%im) both evaluate to k (using the complex part designators introduced by Fortran 2008 for clarity).
Now, the real intrinsic generic takes a complex expression and returns its real component. It does so subject to the following F2008 rule (13.7.138), where A is the argument:
If A is of type complex and KIND is not present, the kind type parameter is the kind type parameter of A.
So, yes: in current Fortran real without a requested kind will always give you a real of kind that of the complex's real component. Whether that's double precision or otherwise.
Similarly, aimag returns a real (corresponding to the imaginary part) of kind that of the complex number. Unlike real, aimag doesn't accept a kind= argument controlling the result kind.
Things are different for Fortran 77: there was no similar concept of kind, and just one complex.
dble is a standard intrinsic. Although this always returns a double precision it is still generic and will accept any numeric. dble(a) is the same as real(a,kind(0d0)), whatever the type of a. There is no (standard) specific.
dreal, dimag and dconjg are not standard intrinsics.
I suppose one could create specific wrappers around real if one cared greatly.
I'm trying to plot a function which has a term with a generalized Laguerre polynomial in it. I know Mathematica can use LaguerreL[n, a, f(x,y)], but I'm not sure what the python equivalent would be. I'm currently trying scipy.special.genlaguerre(n, a, (f(x,y)), using x and y as numpy.arange arrays for the values across which I want to plot. but I keep getting the following error:
The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
so I have 2 questions: 1) am I correct in using special.genlaguerre? (I think so)
2) how do I fix the truth value error that numpy is generating here?
Laguerre polynomials only depend on one variable. You want to evaluate it on x,y positions. In your problem, the one variable you need might be the radius from the origin r.
scipy.special.genlaguerre indeeds generate generalized laguerre polynomials. It returns a np.poly1d function. To evaluate this on a range of numbers:
rs = np.linspace(0,10)
scipy.special.genlaguerre(1, 0)(rs)
In your question, you try to supply f(x,y) as monic parameter to genlaguerre
If you need the evaluate this polynomial at very high accuracy, read this:
Laguerre polynomials in python using scipy, lack of convergence?
Is there an absolute value function for a complex value in double precision? When I try CABS() I get
V(1,j) = R(j,j) + (R(j,j)/cabs(R(j,j)))*complexnorm2(R(j:m,j))
"Error: Type of argument 'a' in call to 'cabs' at (1) should be
COMPLEX(4), not COMPLEX(8)"
I have read there's a function called CDABS() but I wasnt sure if that was the same thing?
There is no reason using anything else than ABS(). Generics for intrinsic procedures were already present in FORTRAN 77. You can use them for all intrinsic numeric types.
If you want to see the table of available specific functions of the generic ABS(), see https://gcc.gnu.org/onlinedocs/gfortran/ABS.html , but they are mostly useful only to be passed as actual arguments. You can see that CDABS() is a non-standard extension and I do not recommend to use it.
CABS is defined by the standard to take an argument of type default complex. In your implementation this looks like complex(kind=4). There is no standard function CDABS, although your implementation may perhaps offer one: read the appropriate documentation.
Further, there is no standard specific function for the generic function ABS which takes a double complex argument. Again, your implementation may offer one called something other than CDABS.
That said, the generic function ABS takes any integer, real, or complex argument. Use that.
COMPLEX*8 and complex(KIND=8) are not the same.
The first one, is 4 byte real and 4 byte imaginary.
The complex(KIND=8) or COMPLEX(KIND=C_DOUBLE) is actually a double precision real and double precision imaginary... So equivalent to COMPLEX*16.
As mentioned ABS() should be fine.