MathGroup Archive 2006

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

Search the Archive

Re: Defining N for a new entity

  • To: mathgroup at smc.vnet.net
  • Subject: [mg66892] Re: Defining N for a new entity
  • From: ab_def at prontomail.com
  • Date: Fri, 2 Jun 2006 04:09:52 -0400 (EDT)
  • References: <200605280103.VAA23345@smc.vnet.net><e5bsuq$afo$1@smc.vnet.net> <e5ei6d$800$1@smc.vnet.net> <e5h5p7$ero$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Peter Pein wrote:
> Giuseppe Bilotta schrieb:
> > On Sun, 28 May 2006 10:10:34 +0000 (UTC), Carl K. Woll wrote:
> >
> >> Giuseppe Bilotta wrote:
> >>> So I was looking for a way to tell Mathematica that applying N to an
> >>> AffineExpression should only actually apply it to c and xi, something
> >>> like
> >>>
> >>> N[AffineExpression[c_, dev_]] :=
> >>>   AffineExpression[N[c], MapAt[N,#,{2}]&/@ dev]
> >>>
> >>> but if I actually do this and then call
> >>>
> >>> AffineExpression[1, {{1, 1}}]
> >>> N[%]
> >>>
> >>> the Mathematica kernel (5.2.0.0) dies without any message.
> >>>
> >>> Does anybody have an idea of what could the reason be? And what could
> >>> I do as a workaround?
> >> One idea is to use the attribute NHoldRest (or if you change your data
> >> structure, NHoldFirst). For example:
> >>
> >> SetAttributes[AffineExpression, NHoldRest]
> >>
> >> In[42]:= N[AffineExpression[.5, {{1, .2}, {2, .1}}]]
> >>
> >> Out[42]= AffineExpression[0.5, {{1, 0.2}, {2, 0.1}}]
> >
> > Thank you very much, this does the trick. It has the rather small
> > side-effect of preventi N from working on the coefficients
> > (N at AffineExpression[.5,{{1,Pi/6}}] will not numerize Pi/6), but it's
> > good enough for my application.
> >
> > Do you have any ideas on why the Mathematica kernel dies without a
> > message?
> >
>
> Salute Giuseppe,
>
>   just guessing...
>
> N[AffineExpression[c_,dev_]]:=... might evaluate the left hand side before applying SetDelayed. This is an explanation, why Mathematica doesn't complain about N being protected.
> But N[AffineExpression[c_,dev_]] evaluates to AffineExpression[c_,dev_], leaving you with a hidden recursion:
>
> N[f[x_]]:=f[N[x]]
> N[f[13]] (* choose your favourite unlucky number here *)
>
> reproduces the crash.
>
> If you don't want the NHoldRest-solution, you might try:
>
> In[1]:=
> a1=AffineExpression[1,{{1,1},{2,Pi}}];
>
> AffineExpression /: HoldPattern[N][AffineExpression[c_, dev_]] :=
>      AffineExpression[N[c], MapAt[N, #, 2]& /@ dev]
>
> N[a1]
> --> AffineExpression[1.,{{1,1.},{2,3.14159}}]
>
> Ciao,
>    Peter

The definition N[f[x_]] := f[N[x]] is stored in NValues[f]. What seems
to be happening is that N[f[1]] evaluates to f[1.] but then Mathematica
looks up NValues for symbols on the next evaluation step as well, and
an infinite loop results:

N[f[x_]] := (Print[x]; f[N[x]]) /; NumericQ[x] && !MachineNumberQ[x]
N[f[1]]
(*works fine, no NValues for f[1.]*)

Clear[f]
N[f[x_]] := (Print[x]; g[N[x]])
N[g[x_]] := (Print[x]; h[N[x]])
N[f[1]]
(*works fine, no NValues for h[1.]*)

N[f[x_]] := (Print[x]; f[N[x]])
N[f[1]]
(*infinite loop*)

The definition for HoldPattern[N][f[x_]] is stored in UpValues[f],
hence the difference.

For AffineExpression we can do something like this:

In[1]:= Attributes[AffineExpression] = NHoldAll;
  N[AffineExpression[c_, dev_]] :=
      AffineExpression[N[c], MapAt[N, #, {2}]& /@ dev] /;
    dev =!= {} && MemberQ[
      Prepend[dev[[All, 2]], c],
      _?(NumericQ[#] && !MachineNumberQ[#]&)]

In[3]:= LinearSolve[{{1.}}, {AffineExpression[1, {{2, 3}, {4, 5}}]}]

Out[3]= {1.*AffineExpression[1., {{2, 3.}, {4, 5.}}]}

NHoldAll is needed to prevent the application of the built-in rules for
N.

Maxim Rytin
m.r at inbox.ru


  • Prev by Date: tensors, matrices, and rotation
  • Next by Date: Re: Re: How to get the maximums of a curve
  • Previous by thread: Re: tensors, matrices, and rotation
  • Next by thread: Re: Defining N for a new entity