MathGroup Archive 1999

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

Search the Archive

Re: An open letter

  • To: mathgroup at smc.vnet.net
  • Subject: [mg16792] Re: An open letter
  • From: "Johan Gunnarsson" <johan at kestrel.edu>
  • Date: Tue, 30 Mar 1999 02:35:05 -0500
  • Organization: Concentric Internet Services
  • References: <7cleqb$9oh@smc.vnet.net> <7ct1oq$82d@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

The responces to this letter have given a good illustration to the problem
of "Hold"-programming in Mathematica.

Jack Goldberg wrote:
> I am fairly confident that this type of problem can be solved by
> a judicious combination of "holds"  and "releaseholds" and "evaluates".

Mark Kraus wrote:
>And HoldForms and all the stuff related (I remember Unevaluated and
>Literal, but never was able to apply these things in a sensible way).

My answer to this is: Forgett about ReleaseHold, Evaluate, and Unevaluated
since these don't really help the idea of how to do Hold-programming in a
structured
way. The answer is simpel pattern matching with Replace.

I will give an alternative implementation of the ByParts. This one will
produce the
left hand side only and not the whole equation which makes ByParts a mapping
from expressions to expression which is prefereable.

SetAttributes[ByParts,HoldAll];

ByParts[HoldForm[Integrate[f_, x_]] | Integrate[f_, x_], HoldForm[g_] | g_ ]
  :=
  Module[{int, nf},
    int = Integrate[g, x];
    nf = f/g;
    Replace[Simplify[{nf*int, int*D[nf, x]}],
      {term_, integrand_} :>
        HoldForm[term - Integrate[integrand, x]]
      ]
    ]

Here how it works:

1. To be able to write or past expression into ByParts we need to prevent
    evaluation by the HoldAll attribute.

2. ByParts returns the whole result wrapped in HoldForm which makes it
    more systematic compared to have HoldForm scattered everywhere in the
    expression. The fix to put HoldForm on the head of Integrate like
            HoldForm[Integrate][....]
   will look nice on the output but the structure is destroyed since the
pattern
   Integrate[_,_] will not match on that. No good.

3. To make the function output fit its input for being able to apply
functions
    several times, the function input must be able to accept HoldForm on
top.
    The input to ByParts above can be both with or without HoldForm.

4. Now the most important, Replace!
    To produce the result of the function without worring about Hold,
Evaluate,
    Unevaluated ....  think as follows:
            Since Replace do rule replacement first and then evaluation you
can't do

                    Replace[HoldForm[....], pattern:>rhs]

            if the rhs contains things that you hope to evaluate. Instead
put the
            structure of the result (or result template) as the rhs of the
rule and put all
            the things that needs to be evaluated in the first position of
the Replace
            and use the rule to put the evaluated expression in place within
the HoldForm,
            like

                Replace[{exp1,exp2,...}, {x1_, x2_, ...}:>HoldForm[....] ]

   It is clear from my experiance (which is code transformation) that
Replace used like
   this will make the code much easier to read compared to all these trix
with Evaluate etc.

Test it

In[102]:=
ByParts[Integrate[x^2 Sin[x], x], Sin[x]] // OutputForm

Out[102]//OutputForm=
   2
-(x  Cos[x]) - Integrate[-2 x Cos[x], x]

Regards

/Johan Gunnarsson
MathCore, http://www.mathcore.com




  • Prev by Date: Re: Re: Precision graphics
  • Next by Date: Re: Plotting multiple outputs from cpu intensive function
  • Previous by thread: Re: An open letter
  • Next by thread: Precision graphics