How is it possible to use a mathematical function as module- parameter
Such as:
PersonalPlot[fun0_, var0_, min0_, max0_] :=
Module[{fun = fun0, var = var0 , min = min0, max = max0},
(*this is incorrect*)
fun = fun[var_];
Plot[fun, {var, min, max}]
]
PersonalPlot[x^2,x,0,3];
You're right, that statement is incorrect. Mathematica evaluates it to something like
x^2[x]
when you call PersonalPlot and that evaluates to, well, in words to x to the power of 2 of x which doesn't make a lot of sense. There are a number of ways round the problem. The simplest would be to dispense with a Module altogether and define:
PersonalPlot1[fun0_, var0_, min0_, max0_] := Plot[fun0, {var0, min0, max0}]
which you would call like this:
PersonalPlot1[x^2, x, 0, 3]
Note that a call like this PersonalPlot1[x^2, y, 0, 3] produces an empty plot because the variable in the function passed in is not the same variable as the second argument. Read on.
If you want to define a module which takes a function as an argument, then this is one way of doing it:
PersonalPlot2[fun0_, var0_, min0_, max0_] :=
Module[{fun = fun0, var = var0, min = min0, max = max0},
Plot[fun[var], {var, min, max}]]
which you would call like this
PersonalPlot2[#^2 &, x, 0, 3]
Note:
The function passed into the function is a pure function. If you are not already familiar with Mathematica's pure functions now would be a good time to consult the relevant parts of the documentation.
This explicitly tells the Plot command to evaluate fun[var] over the range you specify.
Your local variables are not strictly necessary since your function works by side-effect, producing a plot rather than manipulating (copies of) the arguments passed to it. You could rewrite this simply as:
PersonalPlot2b[fun0_, var0_, min0_, max0_] := Module[{},
Plot[fun0[var0], {var0, min0, max0}]]
Another possibility would be to drop the argument which represents the variable input to the function passed to PersonalPlot, like this:
PersonalPlot3[fun0_, min0_, max0_] := Module[{x},
Plot[fun0[x], {x, min0, max0}]]
which you would call like this
PersonalPlot3[#^2 &, 0, 3]
In this version I've made x local to the Module to avoid clashes with any workspace variable also called x. This avoids errors arising from using different names for the argument to the function (the pure function has no argument names) and the second argument to PersonalPlot; that has now been dropped.
There are probably several other useful ways of passing arguments to functions whether those functions use modules or not.
EDIT
Most of us who've used Mathematica for a while don't, I think, regard #^2& as something to avoid. If you don't like it, you could use the more explicit syntax, like this:
fun1 = Function[x,x^2]
which you can then pass around like this
PersonalPlot[fun1,0.0,4.0]
By using this approach you can make your functions a bit less error prone by requiring the right types to be passed in, like this
PersonalPlot[fun_Function, min_Real, max_Real] := ...
but it's really up to you.
Off the top of my head I don't know how Plot does it, I'd have to look in the documentation.
The following three examples may add to previous answer in illustrating some of the possible ways to pass functions as arguments.
Example 1:
square[x_] := x^2/50;
fplot1[f_, x1_, x2_] := Plot[f, {x, x1, x2}];
fplot1[x^2/50, -2 Pi, 2 Pi]
fplot1[{square[x], Sin[x]}, -2 Pi, 2 Pi]
Example 2:
fplot2[f_, x1_, x2_] :=
Module [ (*
This type of function passing works also works in Module so long as x is not defined as a local variable. *)
{},
Plot[f, {x, x1, x2}]
];
fplot2[Sin[x], -2 Pi, 2 Pi]
fplot2[{Sin[x], square[x]}, -2 Pi, 2 Pi]
Example 3:
fplot3[f_, x1_, x2_] :=
Module [ (* This type of function passing works in Module with x declared as local variable. Only one function name can be passed. *)
{x},
Plot[f[x], {x, x1, x2}]
];
fplot3[Sin, -2 Pi, 2 Pi]
fplot3[square, -2 Pi, 2 Pi]
Related
I have a module that generates the nth Taylor polynomial for a function:
taylor[n_, a_] :=
Module[{terms = {f[0]}},
Do[AppendTo[
terms, (D[f[x], {x, i}] /. x -> a)/Factorial[i]*(x - a)^i], {i, 1,
n}]; Return[Plus ## terms]]
Now, I want to call this function such that it generates a list of polynomials. This worked fine with a singular argument and Maping it over a Range. However, in trying to Thread the module like so:
Thread[taylor[Range[7], 0]]
I get an error that
Iterator {i,1,{1,2,3,4,5,6,7}} does not have appropriate bounds.
i.e., n is not being evaluated like I thought it would be, like:
{taylor[1,0], taylor[2,0], ...}
I could change the implementation of the module, but I do not know why Thread is not behaving as expected.
Try this and see if it does what you want
taylor[n_, a_] := Module[{terms = {f[0]}},
Do[AppendTo[terms, (D[f[x], {x, i}] /. x -> a)/Factorial[i]*(x - a)^i], {i, 1,n}];
Return[Plus ## terms]]
Thread[g[{1,2,3},0]]/.g->taylor
which returns
{f[0] + x*f'[0],
f[0] + x*f'[0] + x^2*f''[0]/2,
f[0] + x*f'[0] + x^2*f''[0]/2 + x^3*f'''[0]/6}
What that is doing is all the threading without invoking the way that Module evaluates arguments and once that is finished then handing it to Module to complete. Just make certain that you haven't defined g before you do this.
Check all this very carefully before you depend on it.
I have an array of expressions, each depends on a.
I want to find the minimal positive value, as it depends on a, without having to substitute for a.
For example, if the array is [a^2, 1-2a, 1], then the function, call it MinPositive would return:
(MinPositive[a^2, 1-2a, 1]) /. a-> 0
0
(MinPositive[a^2, 1-2a, 1]) /. a-> 0.7
0.7^2
and so on.
Any ideas?
I would appreciate help to write the MinPositive function so that it can be used, for example, instead of the regular Min function.
Thanks.
Did you have something like this in mind? Return the expression that retsults in the min value..
minp[lst_, a_, v_] := (
pos = Select[lst, ((# /. a -> v) > 0) &];
Last#Sort[pos , ( (#1 /. a -> v ) > (#2 /. a -> v )) &])
minp[{a^2, 1 - 2 a, 1}, a, .2] -> a^2
minp[{a^2, 1 - 2 a, 1}, a, .48] -> 1-2 a
minp[{a^2, 1 - 2 a, 1}, a, 2] -> 1
The expression
[a^2, 1-2a, 1]
is not a well-formed Mathematica expression, perhaps you mean
{a^2, 1-2a, 1}
which is a valid expression for a list of 3 elements. Mathematica doesn't really do arrays as such, though lists can generally be used to model arrays.
On the other hand the expression
MinPositive[a^2, 1-2a, 1]
is a valid call to a function called MinPositive with 3 arguments.
All that to one side, I think you might be looking for a function call such as
MinPositive[{a^2, 1-2a, 1}/.a->0]
in which the value of 0 will be substituted for a inside the call to MinPositive but will not be applied outside that call.
It's not clear from your question whether you want help to write the MinPositive function; if you do, edit your question and make it clear. Further, your question title asks for the maximum positive value, while the body of your question refers to minima. You might want to sort that out too.
EDIT
I don't have Mathematica on this machine so I haven't checked this, but it should be close enough for you to finish off:
minPositive[lst_List] := Min[Select[lst,#>0&]]
which you would then call like this
minPositive[{a^2, 1-2a, 1}]
(NB: I avoid creating functions with a name with an initial capital letter.)
Or, considering your comment, perhaps you want something like
minPositive[lst_List, rl_Rule] := Min[Select[lst/.rl,#>0&]]
which you would call like this:
minPositive[{a^2, 1-2a, 1},a->2]
EDIT 2
The trouble, for you, with an expression such as
(MinPositive[a^2, 1-2a, 1]) /. a-> 0
is that the normal evaluation loop in Mathematica will cause the evaluation of the MinPositive function before the replacement rule is applied. How then can Mathematica figure out the minimum positive value in the list when a is set to a particular value ?
To prevent evaluation of the arguments before calling the body of the function is achieved by setting the attributes of the function to HoldAll (prevents evaluations of all arguments), HoldFirst (prevents the evaluation of the first argument only) or HoldRest (prevents the evaluation of all but the first argument).
In addition, since "a" by itself is not an argument, you need to use Block to isolate it from (potential) definitions for "a"
so
SetAttributes[minPositive, HoldAll]
minPositive[lst_List] := Block[{a},Min[Select[lst /. a -> 0, # > 0 &]]]
and even if you explicitly set a to some other value, say
a=3
than
minPositive[{a^2, 1 - 2 a, 100}]
returns 9 as expected
HTH
yehuda
I can't seem to understand the difference between the behaviour of Plot and PlotLog (and other log-scale plotting functions) in Mathematica. Let's say I have this simple function:
f [a_] := Length[Range[0, a]]
now running Plot[f[x], {x, 1, 10}] yields a correct graph, but when I try
PlotLog[f[x], {x, 1, 10}]
I get no output save the following error:
Range::range: "Range specification in Range[1,x] does not have appropriate bounds."
Looks like the evaluation of x is postponed which makes it impossible to create a list from Range, but why on Earth would it happen to log-scale plotting functions only and how do I handle this issue?
PlotLog doesn't exists. If you use LogPlot it will work correctly.
In any case, you may have problems with that definition. I would recommend to define f like f2[a_Real] := Length[Range[0, a]] or f3[a_?NumericQ] := Length[Range[0, a]]so only numbers will be passed to Range.
For example, with your definition, this will fail:
NIntegrate[f[x], {x, 1, 10}]
During evaluation of In[43]:= Range::range: Range specification in Range[0,x] does not have appropriate bounds. >>
18.
But defining a as NumericQ or Real, it will work.
NIntegrate[f2[x],{x,1,10}]
54.
Regards.
As it is problematic to google strings which contain $ (dollar sign) I couldn't find any explanation to the following output:
{Cos[tmp$132923 + \[Phi]],
Sin[tmp$132926 + \[Phi]],
\[Phi]
}
The question:
What does tmp$xxxx means?
Some background
In `book2.nb' I defined the following function:
g[i_, j_] := {
f1[i, t, f2[b, j], p][[1]],
f1[i, t, f2[b, j], p][[2]],
f3[i, t, p]
}
Where f1,f2,f3 are all defined in another notebook book1.nb, which was initialized and working fine. Furthermore, f1 returns a list and b is a list defined and active.
Now, when I invoke g[1,1] I get an output similar to the one cited above - with this tmp$. Nevertheless, if I try to plot g it works perfectly (using ParametricPlot3D[g[1, 1], {t, 0, 1}, {p, 0, 2 Pi}]). However, if I try to define a variable
V= {
f1[1, t, f2[b, 1], p][[1]],
f1[1, t, f2[b, 1], p][[2]],
f3[1, t, p]
}
where I replace i,j with fixed values. Then V is once again with a tmp$ element, but this time it DOESN'T plot...
You are most likely seeing localized symbols that result through scoping such as Module.
Here is one example. Since the localized symbol x is used to define the global symbol y the temporary symbol x$152 escapes Module.
In[1]:= Module[{x}, y = x]; y
Out[2]= x$152
There are other variations of this process. Suppose you set a unique context for the cell (Evaluation > Notebook's Default Context > Unique to Each Cell Group) and then make an assignment to an explicitly Global symbol:
Global`b = a
Now in another notebook:
In[1]:= b
Out[1]= Notebook$$33`a
Your code probably has a variation of this problem:
f[x_] := Module[{t}, Cos[t]+Cos[x] ]
at which point evaluating this:
f[y]
gives this:
Cos[t$685] + Cos[y]
Often, this means there is a problem with the code.
Either 't' was meant to be passed in as a parameter of 'f':
f[x_,t_] := Module[{}, Cos[t]+Cos[x] ]
or 't' needed to be initialized in some fashion:
f[x_] := Module[{t}, t=2x; Cos[t]+Cos[x] ]
It's perfectly ok to use these unique variables in your code, if you intend to do so. For example, this is one way to write an expression with with many unique variables:
Plus ## Table[Unique[x]^i, {i, 100}]
Right now I have code where some function func executes the way I want it to when I give it specific arguments in its definition (so I make it func[x1_,x2_]:=... and then later I make it func[x1_,x2_,x3_]:=... without changing anything else and it works the way I would like it to). Is there a way to automatically substitute whatever arguments I specify for this function?
UPDATE:
I haven't isolated the problem code yet, but this code here does not do what I want:
(* Clear all stuff each time before running, just to be safe! *)
\
Clear["Global`*"]
data = {{238.2, 0.049}, {246.8, 0.055}, {255.8, 0.059}, {267.5,
0.063}, {280.5, 0.063}, {294.3, 0.066}, {307.7, 0.069}, {318.2,
0.069}};
errors = {{x1, 0.004}, {x2, 0.005}};
getX[x1_, x2_] := 1/x2^2
getY[x__] =
Evaluate[Simplify[
Sqrt[Sum[(D[getX[x], errors[[i]][[1]]] errors[[i]][[2]])^2, {i,
Length[errors]}]]]]
map[action_, list_] := action ### list
y = map[getY, data];
y
getY[2, 3]
This code here does: (gives {67.9989, 48.0841, 38.9524, 31.994, 31.994, 27.8265, 24.3525, 24.3525} for y)
(* Clear all stuff each time before running, just to be safe! *) \ Clear["Global`*"]
data = {{238.2, 0.049}, {246.8,
0.055}, {255.8, 0.059}, {267.5,
0.063}, {280.5, 0.063}, {294.3, 0.066}, {307.7, 0.069}, {318.2,
0.069}}; errors = {{x2, 0.004}, {x1, 0.005}};
getX[x1_, x2_] := 1/x2^2
getY[x1_, x2_] := Evaluate[Simplify[ Sqrt[Sum[(D[getX[x1, x2], errors[[i]][[1]]]
errors[[i]][[2]])^2, {i, Length[errors]}]]]]
map[action_, list_] := action ### list
y = map[getY, data]; y
getY[2, 3]
UPDATE 2:
My math:
I intend to take the square root of the sum of the squares of all the partial derivatives of the getX function. Thus the body of the getY function. Then I want to evaluate that expression for different values of x1 and x2. Thus I have the arguments for getY.
Use __, e.g.
In[4]:= f[x__] = {x}
Out[4]= {x}
In[5]:= f[1,2,3,4,5,6]
Out[5]= {1, 2, 3, 4, 5, 6}
In[6]:= f[a,b,c]
Out[6]= {a, b, c}
Well the issue is that in the first version, with explicit number of arguments, you have used Evaluate to evaluate the right hand side. You can not do this when the number of arguments is variable, because evaluator does not know which signature of getX to use.
So the solution is to replace getY with the following:
getY[x__] := (Simplify[
Sqrt[(D[getX ##
errors[[1 ;; Length[{x}], 1]], {errors[[All, 1]]}].
errors[[All, 2]])^2]]) /.
Thread[errors[[1 ;; Length[{x}], 1]] -> {x}]
This would first use variables from errors list exactly as many as you have supplied in the arguments of getY, compute the derivative symbolically, and then perform the Dot, instead of Sum which is faster. Then the outputs will be the same.
Notice that in your two versions of the code, errors have different values.
Alternatively, you can use Derivative like so:
getY2[x__] :=
Abs[(Derivative[##][getX][x] & ###
IdentityMatrix[Length[{x}]].errors[[All, 2]])]
Using it gives the same result.