Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

This is follow up from a previous question in which @Oleksandr R. suggested the use of a package he developed for splitting a model and data into real and imaginary parts to avoid a problem with FindFit when it encounters complex solutions. I eventually had success with fitting the model in the previous question but now I have moved on to a more complex model and I'm getting an error I don't know how to interpret.

The model is called qres and is defined as:

Clear[ns, ns\[Infinity], m, A, \[CapitalDelta]E, T, a, b, p, qst, \
qobs, R]
\[Theta] = ns/ns\[Infinity];
b = A*Exp[\[CapitalDelta]E/(R*T)];
p = (b/(\[Theta]^-m - 1))^(1/m);

qst = R*T*
Log[Psat[T]/b^(1/m)*(\[Theta]^m/(1 - \[Theta]^m))^((m - 1)/m)] + 
R*T*Z[T] + \[Lambda]p;

qobs = FullSimplify[Integrate[qst, ns]]*.039;

qres = qobs - (513.4933382*ns - 98.64056065*ns^2);

Several variables are dependent functions of ns and T:

R = 8.314;
Psat[85.] = 78896.59231;
Psat[100.] = 323767.1859;
Psat[120.] = 1213037.739;
Psat[140.] = 3168227.12;
Z[85.] = -1.584*10^-13*p^2 - 3.494*10^-7*p + 1;
Z[100.] = -6.147*10^-14*p^2 - 2.185*10^-7*p + 1;
Z[120.] = -2.519*10^-14*p^2 - 1.264*10^-7*p + .9997;
Z[140.] = -4.203*10^-21*p^3 + 3.235*10^-15*p^2 - 8.985*10^-8*p + 1;
\[Lambda]p = 
Piecewise[{{6540.2, Re[p] <= 68890.88832}}, 
3.74853*10^-35*p^6 - 3.91100*10^-28*p^5 + 1.60666*10^-21*p^4 - 
3.33138*10^-15*p^3 + 3.74416*10^-9*p^2 - 3.12419*10^-3*p + 
6723.71];

By choosing values for T and ns as well as guessing at the model parameters ns[Infinity], m, A, [CapitalDelta]E I can see that various parts of the model return the expected numerical results:

T = 140; ns = .5; ns\[Infinity] = 1.3052144404401276; m = \
0.33692827685320603; A = 2907.997380634411; \[CapitalDelta]E = \
-4579.218711936131;
Psat[T]
p
Z[T]
\[Lambda]p
qobs
qres
Clear[T, ns, ns\[Infinity], m, A, \[CapitalDelta]E] 

The data to fit the model to are:

Data = {{0, 85, 0}, {0.131592244`, 85, 3.209459459`}, {0.230286428`, 
85, 2.432432432`}, {0.255592629`, 85, 
2.027027027`}, {0.382123633`, 85, 0.033783784`}, {0.426409484`, 
85, -0.743243243`}, {0.516246497`, 
85, -1.047297297`}, {0.60102227`, 
85, -1.689189189`}, {0.642777502`, 
85, -0.540540541`}, {0.749063545`, 85, 
0.168918919`}, {0.760451336`, 85, -0.472972973`}, {0.762981956`, 
85, 0.27027027`}, {0, 100, 0}, {0.074653293`, 100, 
1.689189189`}, {0.111347284`, 100, 1.689189189`}, {0.127796314`, 
100, 1.689189189`}, {0.212572087`, 100, 
0.033783784`}, {0.269511039`, 100, -1.081081081`}, {0.29481724`, 
100, -1.790540541`}, {0.408695144`, 
100, -4.189189189`}, {0.523838358`, 
100, -5.810810811`}, {0.536491458`, 
100, -6.013513514`}, {0.551675179`, 
100, -6.081081081`}, {0.58710386`, 
100, -6.317567568`}, {0.632655021`, 100, -6.621621622`}, {0, 120, 
0}, {0.072122672`, 120, 0.033783784`}, {0.127796314`, 
120, -0.878378378`}, {0.258123249`, 
120, -1.891891892`}, {0.260653869`, 
120, -5.304054054`}, {0.29481724`, 
120, -5.574324324`}, {0.349225572`, 
120, -6.722972973`}, {0.356817432`, 
120, -8.378378378`}, {0.361878672`, 
120, -8.344594595`}, {0.372001153`, 
120, -8.986486486`}, {0.415021694`, 
120, -10.91216216`}, {0.430205415`, 
120, -10.70945946`}, {0.474491266`, 
120, -12.16216216`}, {0.526368978`, 120, -13.51351351`}, {0, 140, 
0}, {0.051877712`, 140, -0.912162162`}, {0.080979843`, 
140, -1.385135135`}, {0.111347284`, 
140, -2.668918919`}, {0.116408524`, 
140, -2.804054054`}, {0.158163755`, 
140, -4.391891892`}, {0.169551546`, 140, -5}, {0.187265886`, 
140, -5.878378378`}, {0.248000768`, 140, -8.918918919`}};

I have installed Oleksandr R.'s "TransformedFit" package and tried to use it to fit the function qres to the data:

ComplexFit[Data, qres, {{ns\[Infinity], 1.3052144404401276}, {m, 
0.33692827685320603}, {A, 
2907.997380634411}, {\[CapitalDelta]E, -4579.218711936131}} , {ns, 
T}]

I get the error message:

FindFit::nrlnum: "The function value {0.,-69.0731+0.0051321\ (12314.5 +706.69\ (1. +Re  
[Plus[<<2>>]])),-115.452+0.00898117\ (11880.9 +706.69\ (1. +Re[Plus
[<<2>>]])),<<45>>,0.,0. +0.0051321\ (0. +706.69\ Im[Times[<<2>>]+Times[<<2>>]]),<<46>>} 
is not a list of real numbers with dimensions {96} at {TransformedParameter
$11,TransformedParameter$15,TransformedParameter$12,TransformedParameter
    $16,TransformedParameter$13,TransformedParameter$17,TransformedParameter
$14,TransformedParameter$18} = {1.30521,0.,0.336928,0.,2908.,0.,-4579.22,0.}."

I would be grateful for any suggestions.

share|improve this question
    
I tested the package on all of the models discussed on this site that led to problems, but I never tried it with a model as complicated as yours. Let me look into it and I'll get back to you later. –  Oleksandr R. Apr 28 at 9:59
    
Thank you very much @Oleksandr R.. I've tried doing the transformation of the model and data "manually" as in the previous question I asked and got a similar error message: –  Pete in Perth Apr 29 at 2:08
    
FindFit::nrlnum: "The function value {0.,-69.0731+0.0051321\ (12314.5 +706.69\ (1. +Re[Plus[<<2>>]])),<<47>>,0. +3.6268\ Im[-6656.38\ Times[<<2>>]^2.96799-5.7489*10^7\ Times[<<2>>]^5.93598],<<46>>} is not a list of real numbers with dimensions {96} at {ns\[Infinity],m,A,\[CapitalDelta]E} = {1.30521,0.336928,2908.,-4579.22}." –  Pete in Perth Apr 29 at 2:16

1 Answer 1

up vote 0 down vote accepted

Apologies for the delay in replying. I didn't need to look too deeply into the cause of the issue you encountered, because I didn't like the way your model was written, so the first thing I did was to change

Psat[85.] = 78896.59231;
Psat[100.] = 323767.1859;
Psat[120.] = 1213037.739;
Psat[140.] = 3168227.12;
Z[85.] = -1.584*10^-13*p^2 - 3.494*10^-7*p + 1;
Z[100.] = -6.147*10^-14*p^2 - 2.185*10^-7*p + 1;
Z[120.] = -2.519*10^-14*p^2 - 1.264*10^-7*p + .9997;
Z[140.] = -4.203*10^-21*p^3 + 3.235*10^-15*p^2 - 8.985*10^-8*p + 1;

into

Psat[T_] := Piecewise[{
    {78896.59231, T == 85}, {323767.1859, T == 100},
    {1213037.739, T == 120}, {3168227.12, T == 140},
    {Indeterminate, True}
   }];

Z[T_] := Piecewise[{
    {-1.584*10^-13*p^2 - 3.494*10^-7*p + 1, T == 85},
    {-6.147*10^-14*p^2 - 2.185*10^-7*p + 1, T == 100},
    {-2.519*10^-14*p^2 - 1.264*10^-7*p + .9997, T == 120},
    {-4.203*10^-21*p^3 + 3.235*10^-15*p^2 - 8.985*10^-8*p + 1, T == 140},
    {Indeterminate, True}
   }];

after which the problem immediately disappeared, giving what seems to be a sensible result:

ComplexFit[Data, qres, {
  {ns\[Infinity], 1.3052144404401276},
  {m, 0.33692827685320603},
  {A, 2907.997380634411},
  {\[CapitalDelta]E, -4579.218711936131}
 }, {ns, T}, "CoordinateSystem" -> "Real"
]

(* emits FindFit::sszero message *)
(* -> { ns\[Infinity] -> 2.74479, m -> 0.310828, 
        A -> 1586.86, \[CapitalDelta]E -> -4028.45 } *)

One can easily imagine why the former approach might give rise to problems: on the LHS is a pattern that is compared in a MatchQ sense with the argument, so for example Psat[85.] is defined while Psat[85] isn't. Also, supplying an argument corresponding to a temperature for which values are not known does not evaluate, whereas in fact it ought to evaluate to an indeterminate result.

Note that "CoordinateSystem" -> "Real" only forces the values of the parameters to be real; it does not matter for this whether the model contains complex numbers or if it evaluates to a complex result. Since you state in the title that the model is explicitly complex, yet I don't see any complex numbers in its definition, perhaps you wanted complex values for the parameters. I assumed not in the above because I can't see how complex Arrhenius parameters would be meaningful, but maybe I misunderstood something. If so, you can do as you did in the question and specify "CoordinateSystem" -> "Cartesian" (or specify it implicitly by omitting that option entirely), and you will get the best-fitting complex values for the parameters.

share|improve this answer
    
Thank you very much Oleksandr R. I suspected that there might be a problem with how I had formatted the model but I didn't know how to do it better. I work as an engineer but as you might guess, programing and working in the Mathematica language are a little outside my training - I'm working on it but I have a long ways to go. Anyway, I really appreciate your help, in just a couple of post you've taught me some useful things. You're quite right about my only wanting the real part of the solution. –  Pete in Perth May 2 at 10:06
    
@PeteinPerth you're very welcome. Note though that this is not the same thing as just taking the "real part of the solution"--here we additionally force the imaginary part to be zero, so that the solution is purely real. If you allow for a complex result and take its real part, the results will be substantially different (not to mention, not correct). –  Oleksandr R. May 2 at 11:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.