I'll put the question right here, but will add some context below in case someone wonders why the heck I'm trying to do this.
Why is it that I have to do two passes to get the value of the arguments in the call to f1 below?
In[24]:= s = { 10 Cos[-Pi t], -4 Sin[0.23 t]};
In[25]:= f2[a1_, a2_, a3_] := Module[
{a = a1, phi = a3},
Function[
a a2[phi #1]
] (* #1 is the time *)
]
f1 := Function[
f2[#1, #2, #3]
]
In[27]:= l = Cases[s, amp_ trig_ [afreq_ t] -> f1[amp, trig, afreq]]
%[[1]][.33]
Out[27]= {a$1667 Cos[phi$1667 #1] &, a$1667 Sin[phi$1667 #1] &}
(* I expected amp and afreq to have been replaced by
their matched values, and a numerical value here *)
Out[28]= amp Cos[0.33 afreq]
(* It works as I (naïvely) expected when I introduce this temporary symbol, func *)
In[29]:= l = Cases[s, amp_ trig_ [afreq_ t] -> func[amp, trig, afreq]]
% /. func -> f1
%[[1]][.33]
Out[29]= {func[10, Cos, \[Pi]], func[-4, Sin, 0.23]}
Out[30]= {a$1668 Cos[phi$1668 #1] &, a$1669 Sin[phi$1669 #1] &}
Out[31]= 5.09041
Context: I'm a total noob to Mathematica, but I do ok with plenty of other progamming languages. This issue came up in a structural dynamics course I'm teaching, using Mathematica as a support tool. Not that it should matter here, but I'm using it to compute the dynamic response of a SDOF system to a periodic excitation.
I compute the Fourier series expansion of the forcing function, then apply a function that I've written to all terms of the expansion and then sum it all up. I have removed all of the details of this to concentrate on the essence of the problem, but I'd be more than happy to post the entire functions in case it helps.
I come from a hpc background, where we tend to overcomplicate things in search of "efficiency", bear that in mind :) The general ideal is that the response is a function of many physical parameters, and the time, but for a single term of the expansion, only the time varies and the physical parameters are fixed.
I wrote a function that takes all the physical constants and forcing terms, computes some constants as local variables inside a module, and returns a function of time using these constants.
For all terms of the expansion, however, the physical parameters are the same, just the forcing terms are different, so I wrote another function that takes the physical constants, and returns a function that takes only the forcing terms, combines them with the physical parameters and calls the function above, returning a function that depends only on time, and has all that is constant precomputed.
It's worth noticing that the variable that is not local to the module always gets substituted.
Even though the original question has been answered, I'm adding the original functions here as a justification for my roundaboutery...
fresp[F0_, w_, m_, c_, k_, trig_] :=
Module[{phi = ArcTan[k - m w^2, c w], A = F0/Sqrt[(k - m w^2)^2 + (c w)^2]},
Function[ t, A trig[w t - phi]]]
]
tresp[ m_, c_, k_] := Function[
fresp[#1 (*F0*), #2(*w*), m, c, k, #3(*trig*)]
]
mck1 = tresp[2., 2., 3.]
mck2 = tresp[1., 1., 2.]
The idea being that each mck function would represent the response of a different physical system. I apologize if my mind has been poisoned by object orientation :)