[Date Index]
[Thread Index]
[Author Index]
Re: Q: NSolve with conditions
*To*: mathgroup at smc.vnet.net
*Subject*: [mg20092] Re: Q: NSolve with conditions
*From*: Daniel Lichtblau <danl at wolfram.com>
*Date*: Thu, 30 Sep 1999 02:43:07 -0400
*Organization*: Wolfram Research, Inc.
*References*: <7ssfgd$bkj@smc.vnet.net>
*Sender*: owner-wri-mathgroup at wolfram.com
Alphons Fakler wrote:
>
> Hello,
>
> I'm trying to solve a system of linear equations by NSolve. How can I
> restrict the solutions, to a subset, that machtes given conditions.
>
> e.g.:
> GlgSys = {EDTAtot == 0.002,
> EDTA1 == 10^10.26*EDTA*H,
> EDTA2 == 10^6.61*EDTA1*H,
> EDTA3 == 10^2.76*EDTA2*H,
> EDTA + EDTA1 + EDTA2 + EDTA3 == EDTAtot,
> H + 2*EDTAtot == 10^(-14)/H + 2*EDTA2 + 3*EDTA1 + EDTA3 + 4*EDTA};
>
> Following conditions should be kept:
> 0<= EDTA <= 0.002,
> 0<= EDTA1 <= 0.002,
> 0<= EDTA2 <= 0.002,
> 0<= EDTA3 <= 0.002,
> 0<= H <= 10^(-4)
>
> Thanks for your reply
>
> --
> Alphons Fakler
> Zentrum fur Chemische Sensoren
> ETH Technopark
> Technoparkstr. 1
> CH - 8005 Zurich
> Tel. (01) 445-1492
> Fax: (01) 445-1233
> EMail: fakler at chemsens.pharma.ethz.ch
Your first problem will be to get any solutions. This problem is
apparently quite sensitive to the large variation in scales and runs
into trouble at machine precision. To alleviate this I had success by
converting to high precision, as below. Note that I am working in
version 4 of Mathematica, offhand I do not know how earlier versions
will behave.
GlgSys = {EDTAtot - 0.002, EDTA1 - 10^10.26*EDTA*H,
EDTA2 - 10^6.61*EDTA1*H, EDTA3 - 10^2.76*EDTA2*H,
EDTA + EDTA1 + EDTA2 + EDTA3 - EDTAtot,
H + 2*EDTAtot - 10^(-14)/H + 2*EDTA2 + 3*EDTA1 + EDTA3 + 4*EDTA};
exactGlgSys = Rationalize[GlgSys,0];
vars = {EDTA,EDTA1,EDTA2,EDTA3,H,EDTAtot};
Now you can use high precision:
In[7]:= Timing[solns = NSolve[exactGlgSys, vars,
WorkingPrecision->100];]
Out[7]= {1. Second, Null}
In[8]:= Length[solns]
Out[8]= 5
Now you can get the desired solution using Select. I convert to machine
precision just to make it more concise for readability.
func[sol_] := With[{vv=vars/.sol},
0<=vv[[1]]<=.002 && 0<=vv[[2]]<=.002 &&
0<=vv[[3]]<=.002 && 0<=vv[[4]]<=.002 &&
0<=vv[[5]]<= 10^(-4)]
In[12]:= sol = N[Select[solns, func]]
-20
Out[12]= {{EDTA3 -> 4.89993 10 , EDTAtot -> 0.002, EDTA -> 0.00197005,
-10 -13
> EDTA1 -> 0.0000299489, EDTA2 -> 1.01926 10 , H -> 8.35418 10 }}
There is an undocumented experimental technique that allows NSolve to
weed out partial or full candidate solutions as it produces them. This
was developed not so much for convenience but rather for efficiency; In
some instances, say when one seeks only real solutions to a large
polynomial system, the time savings can be tremendous. This is not
really an issue here, where it takes a second to get all solutions, and
essentially no time to discard the unwanted ones. That said, here goes.
Were it not hidden, the usage message would be something like this:
SelectCriterion::usage =
"SelectCriterion is an option for NSolve that determines whether to
keep or discard a root in any variable. The value provided should be a
pure
function. It will be applied to the pair {var, candidate value} to
determine
whether to keep or discard that value. Hence one can use different
criteria
for different variables, provided these criteria are independent of one
another."
To use it in this problem:
In[16]:= soltoo = N[NSolve[N[exactGlgSys,100], vars,
WorkingPrecision->100,
Internal`SelectCriterion->(Switch[#[[1]],
EDTA || EDTA1 || EDTA2 || EDTA3, 0<=#[[2]]<=0.002,
H, 0<=#[[2]]<=10^(-4),
_, True]&)]]
-20
Out[16]= {{EDTA3 -> 4.89993 10 , EDTAtot -> 0.002, EDTA -> 0.00197005,
-10 -13
> EDTA1 -> 0.0000299489, EDTA2 -> 1.01926 10 , H -> 8.35418 10 }}
In[17]:= soltoo===sol
Out[17]= True
Obviously such undocumented features are subject to change or removal;
this should be kept in mind if you intend to use them.
Daniel Lichtblau
Wolfram Research
Prev by Date:
**RE: Select cell**
Next by Date:
**Re: Mathematica 3.0 "Report Summary"**
Previous by thread:
**Re: Q: NSolve with conditions**
Next by thread:
**Allow only Variables >=0**
| |