While other answers are valid, I believe you could just use something as straightforward as
f = Function[t, Evaluate@expression]
Let's see how it works:
In[1]:= expression = 3 + 2 cos[t] + 9 sin[t]
+ 3 cos[2t]
+ 5 cos[3t] + 4 sin[3t]
+ 7 cos[4t] + 5 sin[4t];
In[2]:= ClearAll[f]
In[3]:= f = Function[t, Evaluate@expression]
Out[3]= Function[t, 3 + 2 cos[t] + 9 sin[t]
+ 3 cos[2t]
+ 5 cos[3t] + 4 sin[3t]
+ 7 cos[4t] + 5 sin[4t]]
Then,
In[4]:= f[0]
evaluates:
Out[4]= 3 + 17 cos[0] + 18 sin[0]
(Mathematica only has definitions for capitalized Cos and Sin, that's why no more simplifications for your expression are provided.)
You may skip the rest of the answer if this solution is enough for you, and you are not interested in Mathematica subtleties.
However, there is a subtle aspect that may cause unexpected problems in the future. In[3] would modify the “own values” of symbol f:
In[5]:= OwnValues[f]
Out[5]= {HoldPattern[f] :>
Function[t,
3 + 2 cos[t] + 9 sin[t]
+ 3 cos[2t]
+ 5 cos[3t] + 4 sin[3t]
+ 7 cos[4t] + 5 sin[4t]]}
and if you try to add some modifications to your definition then, you could unexpectedly bump into error:
In[6]:= f[t_, shift_] := shift + f[t]
(Check out the Out[5] error message if you want.) Definitions like the one in In[5] deal with “down values” of f, contrary to “own values”.
You could use a bit more elaborate mechanism for assigning DownValues, in case you plan to use In[6]-like definitions for f extensively in the future:
In[7]:= nameToPattern = # :> Pattern[#, Blank[]] &;
In[8]:= defineWithExplicitArguments[listOfArgs_List, f_, expr_] :=
With[{listOfPatterns = listOfArgs /. nameToPattern /@ listOfArgs}, (
DownValues@f = DeleteCases[DownValues@f, _[_[_@@listOfPatterns], _], 1];
Evaluate[f@@listOfPatterns] := expr)]
In[9]:= defineWithExplicitArguments[singleArgument_, f_, expr_] :=
With[{pattern = singleArgument /. nameToPattern@singleArgument}, (
DownValues@f = DeleteCases[DownValues@f, _[_[_@pattern], _], 1];
Evaluate[f@pattern] := expr)]
Now, let's remove all definitions for f
In[10]:= ClearAll[f]
and we're free to use defineWithExplicitArguments for assigning “down values” to it:
In[11]:= defineWithExplicitArguments[t, f, expression]
In[12]:= f[0]
Out[12]= 3 + 17 cos[0] + 18 sin[0]
Additional definitions would work, too:
In[13]:= f[t_, shift_] := shift + f[t]
In[14]:= f[0, -3]
Out[14]= 17 cos[0] + 18 sin[0]
By the way, the In[13] definition could be added by means of defineWithExplicitArguments, as well. Let's check it:
In[15]:= f[t_, shift_] =.
Here, we redefined “two-arguments version” of f, and it does not calculate the shifted wave anymore:
In[16]:= f[0, -3]
Out[16]= f[0, -3]
Then,
In[17]:= defineWithExplicitArguments[{t, shift}, f, expression + shift]
makes it work again:
In[18]:= f[0, -3]
Out[18]= 17 cos[0] + 18 sin[0]
f[t_] = expressionwhich is the same thing.:=delays evaluation because it has theHoldAllattribute, andEvaluatetakes precedence over that, so in total it's just=– ssch Sep 09 '13 at 18:10lhs:=Evaluate[rhs]is, strictly speaking, not fully equivalent tolhs = rhs, in terms of how the rules are stored internally. In most cases this does not matter, but in some it does. For example:a := Evaluate[Range[10]]. Trying thePartassignment will result in an error. Try e.g.a[[2]] = 1. This won't happen for direct assignment. – Leonid Shifrin Sep 18 '13 at 10:13ahas been assigned a value via:=or via=, which, as you say, matters... In the terminology ofGeneral::noval's documentation: Is there a way to find out whetherais a delayed value orahas an immediate value? – masterxilo Jul 03 '16 at 18:07Language`ExtendedDefinition[a]will have a delayed rule as value ofOwnValuesfor immediate own value, and a list containing one delayed rule for delayed own value. – jkuczm Jul 06 '16 at 13:27f[t_]:=Expand[Evalute[expression]], then theExpandwill not take any effect. – NonalcoholicBeer Dec 04 '18 at 10:40f[t_] := Evaluate[expression[t]//Simplify]orf[t_] := Evaluate[expression[t]//FullSimplify]does this nicely. – Bill N Jan 15 '19 at 12:34