cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
Chris_Ng
Level III

JSL Constrained Minimize - Row by Row Solver Help

Hi There,

 

My objective is to have JSL iterate through values in two columns (x1, x2) which is are used in formulas of other columns until it meets the criteria of [column(y1)- column(y2) = 0 ;column(z1)-column(z2)=0]. Note that the equation I'm trying to solve is a nested non-linear equation where

 

y1 = f1(x1, x2, x3, x4...)

y2 = f2(x1, x2, x3, x4...)

z1 = y1+y2

z2 = independent value

 

In Excel, it was simple enough to just break down the equation into multiple columns to more easily track if there were any calculation errors in between. Then iterate through each row and do a solver to iterate x1 and x2 until the objective criteria is met.

 

In JMP, I'm having difficulties using the Constrained Minimize function to replicate this. Everytime I run the script, its does not look like its converging because the target objective is not met and the values are constantly changing. Also I can only set 1 target objective rather than 2. Below is an example of my JSL code. Note that column_y1 and column_y2 are formula columns that have x1 and x2 variables inside.

dt = Current Datatable();
expr1 = abs(:column_y1[i] - :column_y2[i]); 
x1 = 0.5;
x2 = 0.2;

For Each Row(
    i=Row();
   minfun = Constrained Minimize (expr1, {x1(0.1,0.8), x2(0.01,0.5)},
      <<MaxIter(100000),
      <<ShowDetails(True)
   )
   Show(x1, x2, minfun);
   column(dt, "column_x1")[i] = x1;
   column(dt, "column_x2")[i] = x2;
);

Do you think I need to have the ENTIRE nested equation in the expression for this to work? Or is there something wrong I'm doing here.

 

Any help is greatly appreciated. Thanks! 

 

1 ACCEPTED SOLUTION

Accepted Solutions
peng_liu
Staff

Re: JSL Constrained Minimize - Row by Row Solver Help

In this case, I don't think solving multiple equations simultaneously is the direction to go, because every row in your table involves two variables: parameter1 and parameter2. And they are different variables from row to row, though they have the same name from equation to equation and you put them under the same column.

For simultaneously solving multiple equations using the suggestions that I gave, equations use the same set of variables from equation to equation. Every variable should have just one value.

What you need to do is to translate what you have done in Excel Macros to JSL, e.g. you need to write a bigger JSL loop to go through every row iteratively.

 

For solving equation under a nonlinear constraint, one of my suggestions was to convert a constrained problem to an equivalent unconstrained problem. Assume your constraint is an equality, the following example tries to find the solution to y-exp(x)=0, under constraint y==exp(-x). The solution is the intersection of the two curves, which is at (x,y)=(0,1). The minimizing objective is sum of squared errors of the target equation y-exp(x), and the violation of the constraint y-exp(-x)=0. Notice k is a penalty on the violation , and k is rather large.

Also notice, I intentionally put the initial values far away from the solution, and increase MaxIter, just in case you cannot identify initial values that are not close to the solution.

x = 100;
y = 100;
k = 10000;
minFun = Minimize( (y - exp(x))^2 + k*(y - exp(-x))^2, {x, y} , MaxIter(1000));
Eval List( {x, y, minFun} );
show(x, y, y-exp(x),y - exp(-x))

It is a feasible approach if your actual objective can use.

 

 

View solution in original post

13 REPLIES 13
peng_liu
Staff

Re: JSL Constrained Minimize - Row by Row Solver Help

The code does not run. Would you please elaborate? Also Constrained Minimize expects an expression, but expr1 seems to be a variable holding a value, so there is nothing to optimize.
Chris_Ng
Level III

Re: JSL Constrained Minimize - Row by Row Solver Help

Hi Peng Liu,

 

Yeah the code wouldn't work on itself because it requires my datatable which contains proprietary data that I cannot share unfortunately.

 

In terms of expr1 not containing the term to optimize, I guess the question that I had was that if the terms used in expr1 are FORMULA columns where the optimization variable is contained within, would the constrained minimize still work or do I need to expand the entire equation in expr1 (instead of having it nested). Note I didn't choose to do that because the equation is very long.

 

Please let me know if you need more clarification.

 

Thanks. 

peng_liu
Staff

Re: JSL Constrained Minimize - Row by Row Solver Help

The following example is a hypothetical situation based on your description of the problem.

The column fcol is a formula of other two columns x1 and x2.

The evaluation of fcol depends on two columns x1 and x2, and it won't be affected by outside JSL variables, like the ones in your script.

Finally, the example shows expr1 is a value, not an expression.

 

dt = New Table( "Untitled",
	Add Rows( 1 ),
	New Column( "fcol",
		Numeric,
		"Continuous",
		Format( "Best", 12 )
	),
	New Column( "x1",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values({.5})
	),
	New Column( "x2",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Set Values({.5})
	),
);
dt:fcol << set formula(
	(2 * x1 ^ 2 + 2 * x2 ^ 2) - 2 * x1 * x2 - 4 * x1 - 6 * x2
);
dt:fcol << eval formula;
i=1;
expr1 = abs(dt:fcol[i]);
show(expr1);

I guess what you need is an Expression column, like the following example.

dt = New Table( "Untitled",
	Add Rows( 1 ),
	New Column( "exprcol",
		Expression,
		"None",
		Set Selected,
		Set Values( {(2 * x1 ^ 2 + 2 * x2 ^ 2) - 2 * x1 * x2 - 4 * x1 - 6 * x2} )
	)
);
i=1;
expr1 = dt:exprcol[i];
A = [1 1, 1 5];
b = [2, 5];
minFun = Constrained Minimize(
	expr1,
	{x1( 0, 5 ), x2( 0, 5 )},
	<<lessthanEQ( {A, b} )/*and/or <<GreaterThanEQ({A,b}) and/or <<EqualTo({A,b})*/,
	<<StartingValues( [1, .5] )
);
Eval List( {x1, x2, minFun} );

And expr1 can only be just extracting value from an Expression column. Any further operations other than expression operations will trigger evaluation. For example, the following won't work as expected.

dt = New Table( "Untitled",
	Add Rows( 1 ),
	New Column( "exprcol",
		Expression,
		"None",
		Set Selected,
		Set Values( {(2 * x1 ^ 2 + 2 * x2 ^ 2) - 2 * x1 * x2 - 4 * x1 - 6 * x2} )
	)
);
i=1;
x1 = .5;
x2 = .5;
expr1 = dt:exprcol[i]+2*dt:exprcol[i];//trigger evaluation and fail.
Chris_Ng
Level III

Re: JSL Constrained Minimize - Row by Row Solver Help

Hi Peng Liu,

 

Thanks for the response. I think I understand the issue here:

 

For the scenario where I have:

  • Data Table with 100 rows
  • Column Z = Column Y1 - Column Y2
  • Column Y1 = formula(Column X1, X2, X3..)
  • Column Y2 = formula(Column X1, X2, X3..)

Where the goal is to make Column Z = 0 by setting a value in Column X1 and X2 for each row. 

 

Using Constrained Minimize to make the expression in Column Z = 0 by iterating values in some JSL variable x1 and x2 would not work because Column Y1 and Y2 are formula columns that are evaluated based on values in Column X1 and X2, and are not connected at all to the JSL variable x1 and x2.

 

Looking at how you've setup your script, I think the way I can try to make it work for my case is to have all the nested calculation done inside JSL rather than in formula columns in the datatable. Run the constrained Min function and then saving the results in the data table columns.

 

What do you think ?

peng_liu
Staff

Re: JSL Constrained Minimize - Row by Row Solver Help

Feel like a working approach. So you have just a single expression, because you were setting up formula columns, the expressions must be same for all rows. You need the table, only because you need values for x3, x4, etc., row by row. I cannot be sure how constrained optimization and the target objective of z=0 are relevant here, but the following script shows the big picture of the flow. Replace the setup and optimization accordingly.

 

dt = New Table( "Untitled",
	Add Rows( 3 ),
	New Column( "x1",
		Set Values( [.,.,.] )
	),
	New Column( "x2",
		Set Values( [.,.,.] )
	),
	New Column( "x3",
		Set Values( [2,2,2] )
	),
);
expr0 = expr( (x3 * x1 ^ 2 + 2 * x2 ^ 2) - 2 * x1 * x2 - 4 * x1 - 6 * x2 );

for (irow = 1, irow<=nrow(dt), irow++,
	expr1 = substitute(name expr(expr0), expr(x3), dt:x3[irow]);
	//show(name expr(expr1));
	A = [1 1, 1 5];
	b = [2, 5];
	minFun = Constrained Minimize(
		expr1,
		{x1( 0, 5 ), x2( 0, 5 )},
		<<lessthanEQ( {A, b} )/*and/or <<GreaterThanEQ({A,b}) and/or <<EqualTo({A,b})*/,
		<<StartingValues( [1, .5] )
	);
	Eval List( {x1, x2, minFun} );
	dt:x1[irow] = x1;
	dt:x2[irow] = x2;
);

Chris_Ng
Level III

Re: JSL Constrained Minimize - Row by Row Solver Help

Hi Peng Liu,

 

Thank you, I tried following how you've set min-constrained and it does appear to be working for me now. I basically needed to execute all the calculation in JSL rather than have it in formula columns.

 

Question - Is it possible to solve for two equations simultaneously ? Is it possible to have non-linear constraints ?

 

 

peng_liu
Staff

Re: JSL Constrained Minimize - Row by Row Solver Help

Following two JSL functions might be relevant to your "solving equations" objective. They are for linear equations.

peng_liu_0-1605726799409.png

peng_liu_2-1605726856820.png

For solving nonlinear equations, you may want to convert the objective to an equivalent optimization problem. Then use JSL function Maximize or the Nonlinear platform to solve it.

For optimization with nonlinear constraints, it is possible to construct an equivalent optimization objective without constraints, so some JMP tools can be used, e.g. JSL function Maximize, the Nonlinear platform, or Desirability Function in Profiler. Other JMP tools might be useful for "searching" the optimal, e.g. DOE platforms in JMP.

The choice of approach depends on the actual objective and constraints.

 

Chris_Ng
Level III

Re: JSL Constrained Minimize - Row by Row Solver Help

Hi Peng Liu,

 

Thanks for sharing those options, but its not clear which method I could use if I'm basically trying to do the same thing as before, which is solving for x1 and x2 for each row in the data table but in this case solving two equations simultaneously, with some non-linear constraints.

 

Do you know if we have any examples done before ? It's difficult to believe that it's so difficult to do this vs Excel

 

Thanks

peng_liu
Staff

Re: JSL Constrained Minimize - Row by Row Solver Help

How about posting the Excel example that you said easy to solve, and we start from there? Not necessarily the exact problem in your hands, but something closely resembles your objective. Or just the Excel example that they show you how to use, and we will see whether we can solve it using JMP.