I am using Constrained Minimize() in JSL and would like to build both the objective function and the constraint set dynamically, based on which variables appear in the objective equation.
In simple cases, I can hard-code everything, for example:
R_nom = 0.1;
L_nom = 0.5;
S_nom = 48.2;
B_nom = 0.05;
R_eq = 0.1;
L_eq = 0.5;
S_eq = 48.2;
B_eq = 0.05;
R_sd = :sd_R;
L_sd = :sd_L;
S_sd = :sd_S;
B_sd = :sd_B;
bias_const = 1.5;
R_bias = R_sd * bias_const;
L_bias = L_sd * bias_const;
S_bias = S_sd * bias_const;
B_bias = B_sd * bias_const;
minFun = Constrained Minimize(
(16.388 * Pi() * R_nom ^ 2 * L_nom - B_nom) * S_nom,
{R_nom( R_eq - R_Bias, R_eq + R_Bias ), L_nom( L_eq - L_Bias, L_eq + L_Bias ), S_nom( S_eq - S_Bias, S_eq + S_Bias ),
B_nom( B_eq - B_Bias, B_eq + B_Bias )},
<<tolerance( 0.000000000000001 ),
<<MaxIter( 250 ),
<<UseNumericDeriv( "true" )
);
However, the equation could change dynamically, e.g.:
R_nom^2 * L_nom // instead of 16.388 * Pi() * R_nom ^ 2 * L_nom - B_nom) * S_nom
In that case, I only want constraints for R_nom and L_nom, not for B_nom or S_nom.
What I want to achieve
-
Define the objective function as an expression (Expr()).
-
Determine which input variables are used in the equation (I have a created a function for this
varsUsed = {"R_nom","L_nom"}; //when equation is R_nom^2 * L_nom
-
Automatically build the constraint list only for those variables.
-
Pass the dynamically generated constraint list into Constrained Minimize().
Current Approach
I store parameter metadata (nominal variable, equilibrium value, bias) in an associative array, e.g.:
paramInfo = Associative Array();
paramInfo["R_nom"] = {R_nom, R_eq, R_bias};
paramInfo["L_nom"] = {L_nom, L_eq, L_bias};
paramInfo["S_nom"] = {S_nom, S_eq, S_bias};
paramInfo["B_nom"] = {B_nom, B_eq, B_bias};
Where I am stuck
I am having trouble constructing valid constraint expressions dynamically in JSL so that they are accepted by Constrained Minimize().