1
$\begingroup$

I am trying to evaluate:

For[i = 1, i < 100000, i++, h[0] = hs; 
h[i]=hi /. Check[FindRoot[Xfnew[a, w, hi, mxs + i*step]*92*10^23) == 1198/10000, {hi, h[i - 1]}]]; 
If [h[i] == 25, Break[], AppendTo[hin, {mxs + i*step, h[i]}]]];

where mxs , hs, and step has some values, and hin is initially empty list.

The reason I am using Findroot in a loop, is that my function of Xfnew is seriously complicated, and Findroot can only find solutions very close to the actual solution. So I cannot evaluate Findroot over a wide range. So I am using small steps, and using the previous step's result as the starting point for FindRoot.

If FindRoot cannot evaluate this, then it returns some error message, and the Check option sets the solution to 25, in which case I break the for loop, otherwise it keeps adding to the list.

I want to know if there is a faster way to do the same thing in Mathematica, (like using Table, or other functions which generally people recommend using, over for loop).

Thank you for your help.

$\endgroup$
  • 2
    $\begingroup$ It is generally recommended to use Table in such situations. $\endgroup$ – Alexei Boulbitch Nov 19 '18 at 15:30
  • 1
    $\begingroup$ Can you provide a minimal set of code that works as intended? For example, I can't reproduce the results you're aiming for without a working Xfnew. However, a few things stick out. First, if Xfnew is numerically exact, you're going trying to exactly solve an eqn with something O(10^23) on the LHS and < 1 on the RHS. This may be numerically difficult for an exact method. If you try eg. changing 92 to 92. it might work. Anyway, I would try using Fold, since you want to use the previous solution as input to the next iteration. $\endgroup$ – evanb Nov 19 '18 at 15:31
  • 3
    $\begingroup$ You can also use NestWhileList. $\endgroup$ – Henrik Schumacher Nov 19 '18 at 17:07
4
$\begingroup$

You're creating pairs {m,h} where each pair really only depends on the previous pair. That's perfect for NestWhileList. i is irrelevant, an artifact of procedural formulation: you don't need it. You need two functions. The first transforms an {m,h} pair into a new pair, something like:

f[{m_,h_}]:={m+step,(whatever makes the next h)}

Then, you need a test function, something like:

tf[{m_,h_}]:= h!=25

(although I'd use something like False or $Failed as a termination token rather than a number). Then,

NestWhileList[f,{mxs,hs},tf,1,100000]

will make a list of your results.

$\endgroup$
1
$\begingroup$

An example with Table. f[x_] is a quadratic and every step the constant term changes. The idea is to store the last solution every iteration and use it in next i's solution, THEN store the new solution. I have tried it in various setups (including this) and it works, but feel free to check in your application.

actualroot:=k (* set initially e.g. = 0*)
f[x]:= x^2 - 3 x - a
Table[actualroot=FindRoot[f[x]==0, {x, actualroot}][[1, 2]], {a, 1, 25}]

Output is

{-0.302776, -0.561553, -0.791288, -1., -1.19258, -1.37228, -1.54138, -1.70156, -1.8541, -2., -2.14005, -2.27492, -2.40512, -2.53113, -2.65331, -2.772, -2.88748, -3., -3.10977, -3.21699, -3.32183, -3.42443, -3.52494, -3.62348, -3.72015}

A note: I do not know your original function, but for simplicity my step is to increase a by 1 every iteration, which is a term in f(x). It is straightforward to apply it to your case, I think.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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