Skip to main content
replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
Source Link

We can see that there is a 10^x in the message, which shows that the call to GuessError[.., .., 10^x, etc.] was evaluated with a symbolic x. (NMinimize is not HoldAll or HoldFirst.) This is a classic problem solved by _?NumericQ, which is explained in this answer: What are the most common pitfalls awaiting new users?What are the most common pitfalls awaiting new users?

We can see that there is a 10^x in the message, which shows that the call to GuessError[.., .., 10^x, etc.] was evaluated with a symbolic x. (NMinimize is not HoldAll or HoldFirst.) This is a classic problem solved by _?NumericQ, which is explained in this answer: What are the most common pitfalls awaiting new users?

We can see that there is a 10^x in the message, which shows that the call to GuessError[.., .., 10^x, etc.] was evaluated with a symbolic x. (NMinimize is not HoldAll or HoldFirst.) This is a classic problem solved by _?NumericQ, which is explained in this answer: What are the most common pitfalls awaiting new users?

Added addendum
Source Link
Michael E2
  • 245k
  • 18
  • 351
  • 775

We can see that there is a 10^x in the message, which shows that the call to GuessError[.., .., 10^x, etc.] was evaluated with a symbolic x. (NMinimize is not HoldAll or HoldFirst.) This is a classic problem solved by _?NumericQ, which is explained in this answer: What are the most common pitfalls awaiting new users?

One might add it to other variables except IVcurve, which needs a ?(MatrixQ[#, NumericQ]&) PatternTest.


Gratuitous suggestions

Since NMinimize can be slow, it might be good to speed up GuessError. Depending on how large IVcurve is, since it is static, it would be potentially much faster to construct the NearestFunction just once for the optimization problem.

Next, since it is the position of the nearest point that is desired, it will be more efficient to use the form

Nearest[Vexp -> Automatic]

These two changes speed up NMinimize 35% in a test run on an IVcurve of length 1000, 20% on a curve of length 100.

Further, one can do some more of the construction of the objective function by precomputing Jexp and Vexp which are constant (with respect to ni). With these improvements, the same optimization runs almost 65% faster on a curve of length 1000 (and almost 50% faster on a curve of length 100).

Code:

ClearAll[GuessError, objGuessError];
 (* No pattern tests - Returns an objective function, objGuessError *)
GuessError[IVcurve_, Area_, ni_, mue_, krec_, Jgen_, d_, T_] :=
 objGuessError[
  IVcurve[[All, 1]]/Area^2, IVcurve[[All, 2]],
  Nearest[IVcurve[[All, 1]] -> Automatic],
  Area, ni, mue, krec, Jgen, d, T]; 

objGuessError[Jexp_, Vexp_, iNF_, Area_, ni_?NumericQ, mue_, krec_, Jgen_, d_, T_] := 
 Module[{Vext, q, Vt, Jsim, Vsup, Vinf, ninf, nsup, Jrange, Vrange, 
   Vint, imin, imax, JV}, Vt = 8.61733238 10^-5 (T + 273.15);
  q = 1.6 10^-19;
  Vint = Vt Log[(Jexp + Jgen)/(q d krec ni^2) + 1];
  Vext = Vint + (d Jexp)/(2 q mue ni E^(Vint/(2 Vt)));
  Vinf = Max[First[Vext], First[Vexp]];
  ninf = First[iNF[Vinf]];
  Vsup = Min[Last[Vext], Last[Vexp]];
  nsup = First[iNF[Vsup]];
  Vrange = Take[Vext, {ninf, nsup}];
  Abs@Total[(Vrange - Take[Vexp, {ninf, nsup}])^2]]

Example optimization:

ivcurve = Table[{t, 10^t}, {t, 0, 10, 0.01}];
NMinimize[{GuessError[ivcurve, 1, 10^x, 1, 1, 1, 1, 1], {0.1 < x < 1.5}}, x]

We can see that there is a 10^x in the message, which shows that the call to GuessError[.., .., 10^x, etc.] was evaluated with a symbolic x. This is a classic problem solved by _?NumericQ, which is explained in this answer: What are the most common pitfalls awaiting new users?

One might add it to other variables except IVcurve, which needs a ?(MatrixQ[#, NumericQ]&) PatternTest.

We can see that there is a 10^x in the message, which shows that the call to GuessError[.., .., 10^x, etc.] was evaluated with a symbolic x. (NMinimize is not HoldAll or HoldFirst.) This is a classic problem solved by _?NumericQ, which is explained in this answer: What are the most common pitfalls awaiting new users?

One might add it to other variables except IVcurve, which needs a ?(MatrixQ[#, NumericQ]&) PatternTest.


Gratuitous suggestions

Since NMinimize can be slow, it might be good to speed up GuessError. Depending on how large IVcurve is, since it is static, it would be potentially much faster to construct the NearestFunction just once for the optimization problem.

Next, since it is the position of the nearest point that is desired, it will be more efficient to use the form

Nearest[Vexp -> Automatic]

These two changes speed up NMinimize 35% in a test run on an IVcurve of length 1000, 20% on a curve of length 100.

Further, one can do some more of the construction of the objective function by precomputing Jexp and Vexp which are constant (with respect to ni). With these improvements, the same optimization runs almost 65% faster on a curve of length 1000 (and almost 50% faster on a curve of length 100).

Code:

ClearAll[GuessError, objGuessError];
 (* No pattern tests - Returns an objective function, objGuessError *)
GuessError[IVcurve_, Area_, ni_, mue_, krec_, Jgen_, d_, T_] :=
 objGuessError[
  IVcurve[[All, 1]]/Area^2, IVcurve[[All, 2]],
  Nearest[IVcurve[[All, 1]] -> Automatic],
  Area, ni, mue, krec, Jgen, d, T]; 

objGuessError[Jexp_, Vexp_, iNF_, Area_, ni_?NumericQ, mue_, krec_, Jgen_, d_, T_] := 
 Module[{Vext, q, Vt, Jsim, Vsup, Vinf, ninf, nsup, Jrange, Vrange, 
   Vint, imin, imax, JV}, Vt = 8.61733238 10^-5 (T + 273.15);
  q = 1.6 10^-19;
  Vint = Vt Log[(Jexp + Jgen)/(q d krec ni^2) + 1];
  Vext = Vint + (d Jexp)/(2 q mue ni E^(Vint/(2 Vt)));
  Vinf = Max[First[Vext], First[Vexp]];
  ninf = First[iNF[Vinf]];
  Vsup = Min[Last[Vext], Last[Vexp]];
  nsup = First[iNF[Vsup]];
  Vrange = Take[Vext, {ninf, nsup}];
  Abs@Total[(Vrange - Take[Vexp, {ninf, nsup}])^2]]

Example optimization:

ivcurve = Table[{t, 10^t}, {t, 0, 10, 0.01}];
NMinimize[{GuessError[ivcurve, 1, 10^x, 1, 1, 1, 1, 1], {0.1 < x < 1.5}}, x]
Source Link
Michael E2
  • 245k
  • 18
  • 351
  • 775

I think there is enough information in the question to make a confident guess at the problem. The key clue is in the quoted error message:

Nearest::neard: "The default distance function does not give a real numeric distance when applied to the point pair Max[0.23359984866812222`,-(3.23*10^15\10^-x)/(1+<<23>>\10^(<<5>><<1>><<1>>]))^0.5+ ..."

We can see that there is a 10^x in the message, which shows that the call to GuessError[.., .., 10^x, etc.] was evaluated with a symbolic x. This is a classic problem solved by _?NumericQ, which is explained in this answer: What are the most common pitfalls awaiting new users?

Indeed both calls below yield a Nearest::neard error:

GuessError[Table[{t, 10^t}, {t, 10}], 1, 10^x, 1, 1, 1, 1, 1]
NMinimize[{GuessError[Table[{t, 10^t}, {t, 10}], 1, 10^x, 1, 1, 1, 1, 1],
  {0.1 < x < 1.5}}, x]

The minimal fix is to add a ?NumericQ to ni:

GuessError[IVcurve_, Area_, ni_?NumericQ, mue_, krec_, Jgen_, d_, T_] := ...

One might add it to other variables except IVcurve, which needs a ?(MatrixQ[#, NumericQ]&) PatternTest.