Re: Partial evaulation of function terms
- To: mathgroup at smc.vnet.net
- Subject: [mg53321] Re: Partial evaulation of function terms
- From: Erich Neuwirth <erich.neuwirth at univie.ac.at>
- Date: Thu, 6 Jan 2005 02:51:54 -0500 (EST)
- References: <cr8dve$r5g$1@smc.vnet.net> <crb3do$age$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
It turns out there is a simple solution to my speed problem. Parfun[amps_, freqs_] := Function[t, Apply[Plus, MapThread[#1*Sin[2*Pi*#2*t] &, {amps, freqs}]]] Now Play[Parfun[1/Range[15], 55*2^Range[15]][t], {t, 0, 1}] takes 7.5 seconds, and Play[Evaluate[Parfun[1/Range[15], 55*2^Range[15]][t]], {t, 0, 1}] takes 0.25 seconds, which is a factor of 30 and good enough for my purposes. Is there any reason Play does not automatically do the Evaluate for sound expressions? Peter Pein wrote: > 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 >