Error when using least_squares to solve constrained nonlinear system of equations - least-squares

I'm trying to solve a nonlinear system of 7 equations with least_squares, as some variables are molar fractions and go between 0 and 1 (fsolve doesnt allow constraints as far as I've read). Heres the main part of the code:
def fun_t(w,x_2):
x_1=1-x_2;
z_A=w[0];
z_B=w[1];
z_AB=w[2];
gamma_A=w[3];
gamma_B=w[4];
gamma_AB=w[5];
eps=w[6]
K_gamma=gamma_AB/(gamma_A*gamma_B)
K=K_gamma*z_AB/(z_A*z_B)
phi_A=z_A*v_A/(z_A*v_A+z_B*v_B+z_AB*v_AB);
phi_B=z_B*v_B/(z_A*v_A+z_B*v_B+z_AB*v_AB);
phi_AB=z_AB*v_AB/(z_A*v_A+z_B*v_B+z_AB*v_AB);
return [z_AB-eps/(1-eps),
z_A-(x_2-eps)/(1-eps),
z_B-(x_1-eps)/(1-eps),
eps-(1-(1-4*K/(K+K_gamma)*x_1*x_2)**0.5)/2,
R*T*np.log(gamma_A)-v_A*(alphaT_AB*phi_B**2+alphaT_AAB*phi_AB**2+(alphaT_AB+alphaT_AAB-alphaT_BAB)*phi_B*phi_AB),
R*T*np.log(gamma_B)-v_B*(alphaT_AB*phi_A**2+alphaT_BAB*phi_AB**2+(alphaT_AB+alphaT_BAB+alphaT_AAB)*phi_A*phi_AB),
R*T*np.log(gamma_AB)-v_AB*(alphaT_AAB*phi_A**2+alphaT_BAB*phi_B**2+(alphaT_AAB+alphaT_BAB-alphaT_AB)*phi_A*phi_B)
]
x_2=np.linspace(0,1,11)
guess=[0.5,0.5,0.5,1,1,1,0.25];
roots_t=np.zeros(shape=(len(x_2),len(guess)))
for i in range(len(x_2)):
roots_t[i] = least_squares(fun_t, guess, bounds = ((0,0,0,-5,-5,-5,0),(1,1,1,5,5,5,0.5)), args=x_2[i])
I get the error TypeError: fun_t() argument after * must be an iterable, not numpy.float64. My goal is to give the elements of the array x_2 as the fuction's second argument in order to get the rest of the variables for a set of compositions. I dont understand why it cant iterate over x_2, as it worked when I was using fsolve.
I'm just starting using python for this kind of calculations, so any help will be much appreciated!

Related

How to find out what arguments DM functions should take?

Through trial and error, I have found that the GetPixel function takes two arguments, one for X and one for Y, even if used on a 1D image. On a 1D image, the second index must be set to zero.
image list := [3]: {1,2,3}
list.GetPixel(0,0) // Gets 1
GetPixel(list, 0, 0) // Equivalent
How am I supposed to know this? I can't see anything clearly specifying this in the documentation.
This is best done by using the script function with an incorrect parameter list, running the script, and observing the error output:

Linear optimization doesnot work with upper bounds

I am trying to minimize objective function with scipy linprog.It work good under equilibrium condition,but fails if I define upper bounds.I try several things but could not be able to solve the problem.Here is the code:
c=[0.9,0.25,0.,1.25,4.5,0]
AUB=[[0.99,0.001,0.043,0,0,0.031],[0,0.001,0.01,0.7,0,0.0185],
[0,0,0,0,0.99,0.0045],[1,1,1,1,1,1]]
AEQ=[[0.99,0.001,0.043,0,0,0.031],[0,0.001,0.001,0.7,0,0.0185],
[0,0,0,0,0.99,0.0045],[1,1,1,1,1,1]]
BUB=[3.2,1.85,0.5,100]
BEQ=[2.9,1.5,0.0,100]
res=linprog(c,A_ub=AUB,b_ub=BUB,A_eq=AEQ,b_eq=BEQ,options={"disp":True})
If I change the last line with this code
res=linprog(c,A_eq=AEQ,b_eq=BEQ,options={"disp":True})
or this one
res=linprog(c,A_eq=AEQ,b_eq=BUB,options={"disp":True})
I get 3 different values for objective function.But the minumun is the 3rd one.It should give this result for the 1st function,shouldn't it ?
Any help? Thanks

Gnuplot summation issue

I am trying to make a plot of a simple mutation accumulation process on a binary tree...
My technical problem in gnuplot, is that is that I want to plot the possibility of getting 2 mutations on a specific lineage on the graph, here is the equation which determines it:
P_{2 mutation} = sum[k=0:n] (m/(2**(k+1)/(1-(1/2)**k)))(1-exp(-muk))
(dont bother with the formula im not sure that this is the correct one yet :))
where n is the number of levels of the binary tree, mu is the mutation rate, and m is the number of previously randomly thrown mutations onto the graphs edges...
I want to make a plot which is this possibility depending on the levels of the binary tree...
Therefore I wrote a script which is something like this:
set term pngcairo size 800,600
set title "Két mutáció megjelenésének valószínűsége, egy n szintű bináris fa egyik sejtvonalában"
set xlabel"szintek száma (n)"
set ylabel"Két mutáció megjelenésének valószínűsége (P_{2^{lin})"
set xrange[1:10]
set yrange[0:1]
set output '2mutvalsz.png'
set multiplot
do for[i=1:10]{
mu = 0.1+(i*0.1)
m = 4
f(x)=(x/((2**(x+1))*(1-(0.5)**x)))
if(m<floor(f(x)))
{
p(x)=sum [k=0:floor(x)](m*(1/((2**(x+1))*(1-(0.5)**x))))*(1-exp(-mu*k))
}
else
{
p(x)=1
}
plot p(x) lt i lw 1
}
unset multiplot
set output
So my problem is, that I dont know if it is correct to do what I do in the
if statement...
What I want is to behold the statement m< f(x) where f(x) is the number of edges in respect of n, which is an integer value therefore I use floor(f(x)), and sum through the x values (which are the number of levels what has to be an integer too... so floor(x), like a heavyside function to make the x axis discrete) in the sum...
And also I get an error message:
gnuplot> load '2mutvalsz.plt'
line 27: undefined variable: x
where line 27 is the end of the do for loop...
So my question is that is it a correct way to make a summation integer the x values and of course why I get the error message...
Thank you, and I hope everything is clear...
The error message is produced because the if statement in your script is interpreted when Gnuplot loads the script - it tries to evaluate the condition of the if statement and since the variable x is not defined, it produces the mentioned message.
You could put everything together using the ternary operator as:
p(x)=( m<floor(f(x)) )?( sum [k=0:floor(x)](m*(1/((2**(x+1))*(1-(0.5)**x))))*(1-exp(-mu*k)) ):1;
However, since the function f(x) is on the imposed x-range of [0,1] less than 1, the condition m<floor(f(x)) will be always false.

NLopt with univariate optimization

Anyone know if NLopt works with univariate optimization. Tried to run following code:
using NLopt
function myfunc(x, grad)
x.^2
end
opt = Opt(:LD_MMA, 1)
min_objective!(opt, myfunc)
(minf,minx,ret) = optimize(opt, [1.234])
println("got $minf at $minx (returned $ret)")
But get following error message:
> Error evaluating untitled
LoadError: BoundsError: attempt to access 1-element Array{Float64,1}:
1.234
at index [2]
in myfunc at untitled:8
in nlopt_callback_wrapper at /Users/davidzentlermunro/.julia/v0.4/NLopt/src/NLopt.jl:415
in optimize! at /Users/davidzentlermunro/.julia/v0.4/NLopt/src/NLopt.jl:514
in optimize at /Users/davidzentlermunro/.julia/v0.4/NLopt/src/NLopt.jl:520
in include_string at loading.jl:282
in include_string at /Users/davidzentlermunro/.julia/v0.4/CodeTools/src/eval.jl:32
in anonymous at /Users/davidzentlermunro/.julia/v0.4/Atom/src/eval.jl:84
in withpath at /Users/davidzentlermunro/.julia/v0.4/Requires/src/require.jl:37
in withpath at /Users/davidzentlermunro/.julia/v0.4/Atom/src/eval.jl:53
[inlined code] from /Users/davidzentlermunro/.julia/v0.4/Atom/src/eval.jl:83
in anonymous at task.jl:58
while loading untitled, in expression starting on line 13
If this isn't possible, does anyone know if a univariate optimizer where I can specify bounds and an initial condition?
There are a couple of things that you're missing here.
You need to specify the gradient (i.e. first derivative) of your function within the function. See the tutorial and examples on the github page for NLopt. Not all optimization algorithms require this, but the one that you are using LD_MMA looks like it does. See here for a listing of the various algorithms and which require a gradient.
You should specify the tolerance for conditions you need before you "declare victory" ¹ (i.e. decide that the function is sufficiently optimized). This is the xtol_rel!(opt,1e-4) in the example below. See also the ftol_rel! for another way to specify a different tolerance condition. According to the documentation, for example, xtol_rel will "stop when an optimization step (or an estimate of the optimum) changes every parameter by less than tol multiplied by the absolute value of the parameter." and ftol_rel will "stop when an optimization step (or an estimate of the optimum) changes the objective function value by less than tol multiplied by the absolute value of the function value. " See here under the "Stopping Criteria" section for more information on various options here.
The function that you are optimizing should have a unidimensional output. In your example, your output is a vector (albeit of length 1). (x.^2 in your output denotes a vector operation and a vector output). If you "objective function" doesn't ultimately output a unidimensional number, then it won't be clear what your optimization objective is (e.g. what does it mean to minimize a vector? It's not clear, you could minimize the norm of a vector, for instance, but a whole vector - it isn't clear).
Below is a working example, based on your code. Note that I included the printing output from the example on the github page, which can be helpful for you in diagnosing problems.
using NLopt
count = 0 # keep track of # function evaluations
function myfunc(x::Vector, grad::Vector)
if length(grad) > 0
grad[1] = 2*x[1]
end
global count
count::Int += 1
println("f_$count($x)")
x[1]^2
end
opt = Opt(:LD_MMA, 1)
xtol_rel!(opt,1e-4)
min_objective!(opt, myfunc)
(minf,minx,ret) = optimize(opt, [1.234])
println("got $minf at $minx (returned $ret)")
¹ (In the words of optimization great Yinyu Ye.)

Error due to variable size data in Simulink Matlab function block

I'm working with the Simulink block MATLAB FUNCTION and I'm having problems with the bounds of the variables that I define in there.
This is the part of the code where I’m getting troubles
function P_S1_100= fcn(SOC_S1_100,S1_AGENTS_10,time_CAP_100)
assert(time_CAP_100(1)<100)
tcharging_a1_1=[0:0.05:time_CAP_100(1)]
tcharging_a1_2=[time_CAP_100(1):0.05:time_CAP_100(1)*2]
tcharging_a1=[0:0.05:time_CAP_100(1)]
(Where time_CAP_100 is a vector [1x6])
And this is the error that I'm getting:
Computed maximum size of the output of function 'colon' is not bounded.
Static memory allocation requires all sizes to be bounded.
The computed size is [1 x :?].
Function 'Subsystem1/Slow Charge/S1/MATLAB Function5' (#265.262.302), line 8, column 16:
"[time_CAP_100(1):0.05:time_CAP_100(1)*2]"
Could anyone give me an idea of how to solve this error?
Thanks in advance.
For each of your variable-size data inputs/outputs, you need to define what the upper bound is. See http://www.mathworks.co.uk/help/simulink/ug/declare-variable-size-inputs-and-outputs.html for more details.
Only work around I can think of is to manually write a loop with fixed loop bounds to expand [time_CAP_100(1):0.05:time_CAP_100(1)*2]. That expression is what is causing the problem. You need to know the bounds of this vector. Then you can write a loop something like
% max_size is the maximum length possible for tcharging_a1_2
tcharging_a1_2 = zeros(1,max_size);
tcharging_a1_2(1) = time_CAP_100(1);
for ii=2:max_size
if tcharging_a1_2(ii) < time_CAP_100(1)*2
tcharging_a1_2(ii) = tcharging_a1_2(ii) + .05;
end
end