For Programmers: Free Programming Magazines  


Home > Archive > Mathematica > February 2007 > conditional is giving wrong value









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author conditional is giving wrong value
Peter Jay Salzman

2007-02-25, 4:16 am

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

David Bailey

2007-02-26, 8:16 am

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


dh

2007-02-27, 8:21 am



Hi Peter,

the precision of your "x" variables decreases continually. Is your

algorthm stable? Anyway, if the precision has reached 2 digits, another

quirck of mathematica emerges, namly:

1`2 > 0 gives False

why this is so I can not tell, but I will post this to the group.

Daniel



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


>




Andrzej Kozlowski

2007-02-28, 4:19 am

To avoid this phenomenon (loss of precision in iterative procedures)
you can switch to fixed precision arithemtic by means of the
following trick.

Note first that:


Precision[(2`10)^10000]


6.

In other words, we lost 4 digits. Now the same computation with fixed
pecision:


Block[{$MaxPrecision=10,$MinPrecision=10
},Precision[(2`10)^1000]]


10.


Andrzej Kozlowski


On 27 Feb 2007, at 11:54, dh wrote:

>
>
> Hi Peter,
>
> the precision of your "x" variables decreases continually. Is your
>
> algorthm stable? Anyway, if the precision has reached 2 digits,
> another
>
> quirck of mathematica emerges, namly:
>
> 1`2 > 0 gives False
>
> why this is so I can not tell, but I will post this to the group.
>
> Daniel
>
>
>
> Peter Jay Salzman wrote:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



Jens-Peer Kuska

2007-02-28, 4:19 am

Hi,

and you are sure that you don't mean

While[delta > tolerance,
....
]

and you can't use

myGrad[fun_,var_]:=D[fun,#] & /@ var

to define your own gradient in any dimension you like.

If you don't like the spell and spell1 message than turn it of
with

Off[General::spell]
Off[General::spell1]

and you can name your variables tolerance and min and you
with out a message.

In Mathematica every function return a value, but some guys
like to do procedual programming and to return "No Value"
as a function result the "No Value" has the name Null

Regrads
Jens

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
>


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com