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
| |
|
|
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
>
|
|
|
|
|