MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: conditional is giving wrong value

  • To: mathgroup at smc.vnet.net
  • Subject: [mg73710] Re: conditional is giving wrong value
  • From: David Bailey <dave at Remove_Thisdbailey.co.uk>
  • Date: Mon, 26 Feb 2007 06:09:58 -0500 (EST)
  • References: <errljn$86m$1@smc.vnet.net>

Peter Jay Salzman wrote:
> I'm implementing the method of steepest descent to minimize a function in
> Mathematica and have a few nagging problems, the most serious being that a
> conditional is giving a wrong value.
> 
> Here's my code:
> 
> 
> (* Cell one ========================================================= *)
> 
> Clear[a, delf, delta, f, iteration, min, s, theA, tolerance, x, xNew ];
> << Calculus`VectorAnalysis`;
> 
> 
> (* Function to minimize *)
> f[x_,y_] := 1/2 * x^2  +  1/2 * y^2
> 
> (* Initial Guess. *)
> x  =  { {5.0`20, 1.0`20} }
> 
> (* Direction that points "downhill" from current location. *)
> s  =  {};
> 
> (* The gradient of the function to minimize *)
> (*
>    This doesn't work:
>    delf[x_,y_] := - Grad[f[x,y], Cartesian[x,y,z]];
>    delf[3,1]
> )*
> delf[x_,y_] := { x, 5*y };
> 
> 
> (* Cell two ========================================================= *)
> 
> 
> iteration = 0;
> tolerance = 10^(-30);
> delta = 10;
> 
> 
> While delta > tolerance,
> 
>    Print[{delta, N[tolerance], delta > tolerance}];
> 
>    (* Get direction to travel in (downhill) from grad f.  Ugly syntax! *)
>    s = Append[s, -delf[Last[x][[1]], Last[x][[2]]]];
>    Print["s: ", s];
> 
>    (* a tells us how far to travel.  Need to minimize f to find it. *)  
>    xNew = Last[x] + a*delf[Last[x][[1]], Last[x][[2]]];
> 
>    (* Minimize f wrt a.  Can I do this without using temp var theA? *)
>    {min, theA} = Minimize[f[xNew[[1]], xNew[[2]]], {a}];
>    Print["f at minimum of ", min, " when ", theA];
> 
>    (* Update x using the direction *)
>    xNew = xNew /. theA;
>    delta = Norm[Last[x] - xNew];
>    Print[delta];
>    x = Append[x, xNew /. theA];
> 
>    Print["The new x is ", N[xNew], 20];
>    iteration += 1;
> ]
> 
> Print["Convergence in ", iteration, " iterations."];
> Print["Minimum point at ", Last[x]];
> Print["Value of f at min point: ", f[Last[x][[1]], Last[x][[2]]] ];
> 
> (* ================================================================== *)
> 
> 
> 
> The most serious problem is that this program always terminates at the 23rd
> iteration.   At the last iteration, this line:
> 
>    Print[{delta, N[tolerance], delta > tolerance}];
> 
> prints:
> 
>    { 0.00046, 1.0x10^(-30), True }
> 
> which indicates that 4.6^-4 > 1.0^-30 is true.  What am I doing wrong??
> 
> 
> 
> Other less serious issues that I can live with:
> 
> 1. I'd like to define the gradient of the trial function without me
> explicitly finding the gradient.  For this f, it's nothing, but in
> principle, finding the gradient can be very tedious.  This doesn't work:
> 
>     delf[x_,y_] := - Grad[f[x,y], Cartesian[x,y,z]];
> 
> because when I type delf[3,2], the arguments get passed to Cartesian[] as
> {3,2,z}.  How can I get around this?
> 
> 
> 2. The first time I run this, Mathematica complains that "tolerance" is
> similar to "Tolerance" and "min" is similar to "Min.  How can I supress
> that?
> 
> 
> 3. When I run the first cell (the material above "new cell") Mathematica
>    prints out "Null^6".  What does this mean and why is it getting printed?
> 
> 
> 4. Any coding tips I should keep in mind to become a better Mathematica programmer?
> 
> Many thanks!
> Pete
> 
As regards your first point, surely  0.00046 > 1.0x10^(-30) *is* true!

One way to suppress specific spelling errors (without suppressing the 
mechanism completely) is to execute a cell such as:

ToExpression["{min,Min,tolerance,Tolerance}"]

This will create the symbols algorithmically and will avoid spelling 
diagnostics.

Since you are working to machine precision, your numbers will only have 
about 16 digits of precision, so your tolerance is probably too small, 
assuming you are dealing with quantities of order of magnitude 1.0.

In general, you should think in terms of functions - not cells. Notebook 
cells are places to store portions of code - not computational units. A 
well structured Mathematica program will usually consist of a series of 
(probably interconnected) function definitions, followed by one or more 
invocations of those functions. In particular, cell 2 would be better 
encapsulated as a function.

David Bailey
http://www.dbaileyconsultancy.co.uk



  • Prev by Date: Re: showing an expression equal to 0
  • Next by Date: Re: showing an expression equal to 0
  • Previous by thread: conditional is giving wrong value
  • Next by thread: Re: conditional is giving wrong value