MathGroup Archive 2005

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

Search the Archive

Re: Partial evaulation of function terms

  • To: mathgroup at smc.vnet.net
  • Subject: [mg53245] Re: Partial evaulation of function terms
  • From: Peter Pein <petsie at arcor.de>
  • Date: Mon, 3 Jan 2005 04:29:22 -0500 (EST)
  • References: <cr8dve$r5g$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Erich Neuwirth wrote:
> I have the following function definition
> 
> ParFun[amps_, freq_] := Function[t, Sum[amps[[i]]*Sin[2*Pi*freq*i*t], {
>      i, Length[amps]}]]
> 
> Then, the following works:
> 
> ParFun[{1,1/2},220][t]//InputForm
> Sin[440*Pi*t] + Sin[880*Pi*t]/2
> 
> but
> ParFun[{1,1/2},220]//InputForm
> 	yields
> Function[t$, Sum[{1, 1/2}[[i]]*Sin[2*Pi*220*i*t$], {i, Length[{1, 1/2}]}]]
> 
> Is there a way to force Mathematica to evaluate all
> subterms which already can be evaluated?
> This function will be called in Play very often, so it would make things 
> much faster if you could assign the function with all possible
> constants evaluated to a local variable and do the many calls to the 
> function for producing numerical values with the "partially 
> preevaluated" expression.
   ^^^^^^^^^^^^
You almost got it!

You can speed things further up by using floats instead of exact numbers 
and by compiling the function:

In[1]:=
ParFun[amps_, freq_] := Function[t, Sum[amps[[i]]*Sin[2*Pi*freq*i*t], 
{i, Length[amps]}]]

f1 is the original function:

In[2]:=
f1 = ParFun[1./Range[15], 440.]
Out[2]=
Function[t$, Sum[{1., 0.5, 0.3333333333333333, 0.25, 0.2, 
0.16666666666666666,
       0.14285714285714285, 0.125, 0.1111111111111111, 0.1, 
0.09090909090909091,
       0.08333333333333333, 0.07692307692307693, 0.07142857142857142,
       0.06666666666666667}[[i]]*Sin[2*Pi*440.*i*t$],
    {i, 1, Length[{1., 0.5, 0.3333333333333333, 0.25, 0.2, 
0.16666666666666666,
       0.14285714285714285, 0.125, 0.1111111111111111, 0.1, 
0.09090909090909091,
       0.08333333333333333, 0.07692307692307693, 0.07142857142857142,
       0.06666666666666667}]}]]

Map Evaluate onto f1 to get a preevaluated version:

In[3]:=
f2 = Evaluate /@ f1
Out[3]=
Function[t$, 1.*Sin[2764.601535159018*t$] + 0.5*Sin[5529.203070318036*t$] +
    0.3333333333333333*Sin[8293.804605477053*t$] + 
0.25*Sin[11058.406140636072*t$] +
    0.2*Sin[13823.00767579509*t$] + 
0.16666666666666666*Sin[16587.609210954106*t$] +
    0.14285714285714285*Sin[19352.210746113127*t$] + 
0.125*Sin[22116.812281272145*t$] +
    0.1111111111111111*Sin[24881.413816431163*t$] + 
0.1*Sin[27646.01535159018*t$] +
    0.09090909090909091*Sin[30410.616886749198*t$] +
    0.08333333333333333*Sin[33175.21842190821*t$] + 0.07692307692307693*
     Sin[35939.81995706724*t$] + 
0.07142857142857142*Sin[38704.421492226254*t$] +
    0.06666666666666667*Sin[41469.02302738527*t$]]

and compile it:

In[4]:=
f3 = f2 /. HoldPattern[Function[var_, expr_]] :> Compile[{var}, expr]
Out[4]=
CompiledFunction[]

In[5]:=
{t1, t2, t3} = First /@
    (Timing[snd = Sound[SampledSoundList[
      Table[#1[t], {t, 0, 1, 1./22050}], 22050]]; ] & ) /@ {f1, f2, f3}
Out[5]=
{2.3129999999999997*Second, 1.2810000000000001*Second, 
0.21899999999999986*Second}

Peter

-- 
Peter Pein
Berlin


  • Prev by Date: Re: Partial evaulation of function terms
  • Next by Date: Re: direct product of two sets
  • Previous by thread: Re: Partial evaulation of function terms
  • Next by thread: Re: Partial evaulation of function terms