I am using gekko to solve a system of equations. As an intermediate step I am using an intermediate that plugs the MV temperature into the following function:
def riedelVP(T, const):
'''Returns Vapor Pressure
INPUTS
:T - Temperature (K)
:const - A, B, C, D, E constants for eqn
OUTPUTS
:Y - Pressure in Pascals'''
# unpack constants
a, b, c, d, e = const
# plug into equation
Y = np.exp(a+b/T+c*np.log(T) + d*T**e)
return Y
When I do this, I get the following Error:
I have tried using T.value and T.value[0] as arguments into the function instead of T.
TypeError: loop of ufunc does not support argument 0 of type GKVariable which has no callable log method
How can I use a function with exp and log in a gekko intermediate
The problem in this case is that both the np.exp() function and the np.log function require an argument that is a float, while gekko variables are their own type. If you were to use gekko's methods for exponentiation and taking the logarithm in the function, it will work. To do so, use the m.exp or m.log methods. In this example, I already had a gekko model created using m = GEKKO(), then I could create the function:
def riedelVP(T, const):
'''Returns Vapor Pressure
INPUTS
:T - Temperature (K)
:const - A, B, C, D, E constants for eqn
OUTPUTS
:Y - Pressure in Pascals'''
# unpack constants
a, b, c, d, e = const
# plug into equation
Y = m.exp(a+b/T+c*m.log(T) + d*T**e)
return Y
Use gekko's analogous methods when type errors in functions occur.
Related
I have curve that initially Y increases linearly with X, then reach a plateau at point C.
In other words, the curve can be defined as:
if X < C:
Y = k * X + b
else:
Y = k * C + b
The training data is a list of X ~ Y values. I need to determine k, b and C through a machine learning approach (or similar), since the data is noisy and refection point C changes over time. I want something more robust than get C through observing the current sample data.
How can I do it using sklearn or maybe scipy?
WLOG you can say the second equation is
Y = C
looks like you have a linear regression to fit the line and then a detection point to find the constant.
You know that in the high values of X, as in X > C you are already at the constant. So just check how far back down the values of X you get the same constant.
Then do a linear regression to find the line with value of X, X <= C
Your model is nonlinear
I think the smartest way to solve this is to do these steps:
find the maximum value of Y which is equal to k*C+b
M=max(Y)
drop this maximum value from your dataset
df1 = df[df.Y != M]
and then you have simple dataset to fit your X to Y and you can use sklearn for that
I am trying to minimize the function || Cx - d ||_2^2 with constraints Ax <= b. Some information about their sizes is as such:
* C is a (138, 22) matrix
* d is a (138,) vector
* A is a (138, 22) matrix
* b is a (138, ) vector of zeros
So I have 138 equation and 22 free variables that I'd like to optimize. I am currently coding this in Python and am using the transpose C.T*C to form a square matrix. The entire code looks like this
C = matrix(np.matmul(w, b).astype('double'))
b = matrix(np.matmul(w, np.log(dwi)).astype('double').reshape(-1))
P = C.T * C
q = -C.T * b
G = matrix(-constraints)
h = matrix(np.zeros(G.size[0]))
dt = np.array(solvers.qp(P, q, G, h, dims)['x']).reshape(-1)
where np.matmul(w, b) is C and np.matmul(w, np.log(dwi)) is d. Variables P and q are C and b multiplied by the transpose C.T to form a square multiplier matrix and constant vector, respectively. This works perfectly and I can find a solution.
I'd like to know whether this my approach makes mathematical sense. From my limited knowledge of linear algebra I know that a square matrix produces a unique solution, but is there is a way to run the same this to produce an overdetermined solution? I tried this but solver.qp said input Q needs to be a square matrix.
We can also parse in a dims argument to solver.qp, which I tried, but received the error:
use of function valued P, G, A requires a user-provided kktsolver.
How do I correctly setup dims?
Thanks a lot for any help. I'll try to clarify any questions as best as I can.
I'm attempting to solve the familiar mean-variance optimization problem using matrices in Mathematica, with a few added constraints on the solution vector "w". (The mean-variance optimization problem is basically choosing how to allocate a given budget over a number of assets according to their means and covariances in order to minimize the risk of the portfolio for a chosen level of mean return.)
My question: I'm not sure which function to use to perform the minimization of the objective function, which is quadratic:
obj = 0.5*w'* Sig * w
where w is the Nx1 vector of weights for each of the N assets and Sig is the NxN covariance matrix
From what I've been able to find (I'm fairly new to Mathematica), it seems that FindMinimum, NMinimize, etc. are meant to deal only with scalar inputs, while LinearProgramming is meant for an objective function that's linear (not quadratic) in the weight vector w. I could very well be wrong here--any help in steering me toward the correct function would be much appreciated!
If it helps, I've attached my sample code--I'm not sure how, but if there's a place to upload the sample .csv data, I can do that as well if someone could point me to it.
Thank you very much for any help you can provide.
-Dan
CODE
(* Goal: find an Nx1 vector of weights w that minimizes total \
portfolio risk w'*Sig*w (where Sig is the covariance matrix) subject to:
-The portfolio expected return is equal to the desired level d: w'*M \
= d, where M is the Nx1 vector of means
-There are exactly two assets chosen from each of the refining, \
construction, hitech, and utility sectors, and exactly one asset \
chosen from the "other" sector
^ The above two constraints are represented together as w'*R = k, \
where R is the matrix [M SEC] and k is the vector [d 2 2 2 2 1]
-Each weight in w takes an integer value of either 0 or 1, \
representing buying or not buying that physical asset (ex. a plant) -- \
this constraint is achieved as a combination of an integer constraint \
and a boundary constraint
**Note that for the T=41 days of observations in the data, not every \
asset generates a value for every day; by leaving the days when the \
asset is "off" as blanks, this shouldn't affect the mean or \
covariance matrices.
*)
Clear["Global`*"]
(* (1) Import the data for today *)
X = Import["X:\\testassets.csv", "Data"];
Dimensions[X];
(* (2) Create required vectors and matrices *)
P = Take[X, {2, 42}, {4}];
Dimensions[P]; (* Should be N assets x 1) *)
r = Take[X, {2, 42}, {10, 50}];
Dimensions[r]; (* Should be N x T *)
Sig = Covariance[
r]; (* When there's more time, add block diagonal restriction here \
*)
Dimensions[Sig]; (* Should be N x N *)
M = Mean[r\[Transpose]];
Dimensions[M]; (* Should be N x 1 *)
SEC = Take[X, {2, 42}, {5, 9}];
Dimensions[SEC]; (* Should be N x 5 *)
(* (3) Set up constrained optimization *)
d = 200; (* desired level of return *)
b = 60000;(* budget constraint *)
R = Join[M, POS];
Dimensions[R]; (* Should be N x 6 *)
k = {d, 2, 2, 2, 2, 1};
obj = w*Sig*w\[Transpose];
constr = w*R;
budgetcap = w*P;
lb = ConstantArray[0, 41];
ub = ConstantArray[1, 41];
FindMinimum[{obj, constr = k, budgetcap <= b, Element[w, Integers],
lb <= w <= ub}, w]
What I am doing is generic and has been done a thousand times, but I can't figure out how other programmers do this.
I am working with the Law of Sines to return an angle of A. There are two combinations, for instance:
Return Angle A given (side b, side a, angle B)
Return Angle A given (side c, side a, angle C)
----Note: All together there would be six, two for each angle)----
I can't overload the functions because the signatures are not unique. The parameters and return type are primitive type Double.
The use of Aliases works for reading the code but does nothing to resolve my issue.
One approach I thought of was to create a structure for each side and angle; however, I don't want to create any more complexity than needed.
Another solution could be using a strategy design pattern?
I'm a hobbyist programmer (still beginner level);I'm trying to build some good programming practices. Any help would be appreciated.
I would recommend a different naming convention and a boolean parameter:
Public Function GetAngle(adjacentSide As Double, oppositeSide As Double, knownAngle As Double, Optional knownAngleCorrespondsToAdjacentSide As Boolean = True) As Double
When called, you now know if it's:
GetAngle(c, a, C) 'or
GetAngle(b, a, B) 'or
GetAngle(b, a, C, False) 'or
GetAngle(c, a, B, False)
That said, since A, B, & C are arbitrary labels:
a b c
__________ __________ __________
\B C/ \C A/ \A B/
\ / \ / \ /
c \ / b => a \ / c => b\ / a
\ A/ \ B/ \ C/
\/ \/ \/
you either need two functions (Private would work fine) or just handle your calculations internally base on the boolean:
Public Function GetAngle(adjacentSide As Double, oppositeSide As Double, knownAngle As Double, Optional knownAngleCorrespondsToAdjacentSide As Boolean = True) As Double
If knownAngleCorrespondsToAdjacentSide Then
'Calculate one way
' or call private method
Else
'Calculate the other
' or call the other private method
End If
Return calculatedAngle
End Function
Probably the best thing to do would be to use one method. Your method's signature would look something like this:
Public Function GetAngle(commonSide As Double, commonAngle As Double, otherSide As Double) As Double
Your method would return the other, target angle of the triangle. I couldn't really think of better parameter names, though.
ASCII art time!
a
__________
\B C/
\ /
c \ / b
\ A/
\/
Given that b and B can be transposed with c and C, there are only three formulas you need:
A = ƒ(a, b, B), transpose (b, B) for (c, C) if necessary.
A = ƒ(a, b, C), transpose (b, C) for (c, B) if necessary.
A = ƒ(b, c, B), transpose (B) for (C) if necessary.
Given theses all have two lengths and an angle, you'll need three different method names:
GetAngleFromOppositeLineAndLooseAngle(oppositeLine , adjacentLine , looseAngle)
GetAngleFromOppositeLineAndJointAngle(oppositeLine , adjacentLine , jointAngle)
GetAngleFromAdjacentLines (adjacentLine1, adjacentLine2, looseAngle)
Otherwise, yes you'll have to pass a structure and discern the missing information. Use Nullable(Of Double) or Double.NaN to pass unknown values.
Suppose I have a substitution S and list Xs, where each variable occurring in Xs also occurs in S. How would I find the list S(Xs), i.e., the list obtained by applying the substitution S to the list Xs.
More concretely, I have a set of predicates and DCG rules that look something like
pat(P) --> seg(_), P, seg(_).
seg(X,Y,Z) :- append(X,Z,Y).
If I attempt to match a pattern P with variables against a list, I receive a substitution S:
?- pat([a,X,b,Y],[d,a,c,b,e,d],[]).
X = c,
Y = e
I want to apply the substitution S = {X = c, Y = e} to a list Xs with variables X and Y, and receive the list with substitutions made, but I'm not sure what the best way to approach the problem is.
If I were approaching this problem in Haskell, I would build a finite map from variables to values, then perform the substitution. The equivalent approach would be to produce a list in the DCG rule of pairs of variables and values, then use the map to find the desired list. This is not a suitable approach, however.
Since the substitution is not reified (is not a Prolog object), you can bind the list to a variable and let unification do its work:
?- Xs = [a,X,b,Y], pat(Xs,[d,a,c,b,e,d],[]).
Xs = [a, c, b, e],
X = c,
Y = e .
Edit: If you want to keep the original list around after the substitution, use copy_term:
?- Xs = [a,X,b,Y], copy_term(Xs,Ys), pat(Xs,[d,a,c,b,e,d],[]).
Xs = [a, c, b, e],
X = c,
Y = e,
Ys = [a, _G118, b, _G124] .