Related
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'm trying to write a short piece of code that will perform propagation of errors. So far, I can get Mathematica to generate the formula for the error delta_f in a function f(x1,x2,...,xi,...,xn) with errors dx1,dx2,...,dxi,...dxn:
fError[f_, xi__, dxi__] :=
Sum[(D[f[xi], xi[[i]]]*dxi[[i]])^2, {i, 1, Length[xi]}]^(1/2)
where fError requires that the input function f has all of its variables surrounded by {...}. For example,
d[{mv_, Mv_, Av_}] := 10^(1/5 (mv - Mv + 5 - Av))
FullSimplify[fError[d, {mv, Mv, Av}, {dmv, dMv, dAv}]]
returns
2 Sqrt[10^(-(2/5) (Av - mv + Mv)) (dAv^2 + dmv^2 + dMv^2)] Log[10]
My question is, how can I evaluate this? Ideally I would like to modify fError to something like:
fError[f_, xi__, nxi__, dxi__]
where nxi is the list of actual values of xi (separated since setting the xi's to their numerical values will destroy the differentiation step above.) This function should find the general formula for the error delta_f and then evaluate it numerically, if possible. I think the solution should be as simple as a Hold[] or With[] or something like that, but I can't seem to get it.
I'm not following everything that you've done, and since this was posted two years ago it's likely you aren't working on it anymore anyways. I'll give you my solution for error propagation in hopes that it will somehow help you or others.
I tried to include the best documentation that I could in the video and files linked below. If you open the .cdf file and weed through it you should be able to see my code...
Files:
https://drive.google.com/file/d/0BzKVw6gFYxk_YUk4a25ZRFpKaU0/view?pli=1
Video Tutorial:
https://www.youtube.com/watch?v=q1aM_oSIN7w
-Brian
Edit:
I posted the links because I couldn't attach files and didn't want to post code with no documentation for people new to mathematica. Here's the code directly. I would encourage anyone finding this solution helpful to take a quick look at the documentation because it demonstrates some tricks to improve productivity.
Manipulate[
varlist = ToExpression[variables];
funct = ToExpression[function];
errorFunction[variables, function]
, {variables, "{M,m}"}, {function, "g*(M-m)/(M+m)"},
DisplayAllSteps -> True, LabelStyle -> {FontSize -> 17},
AutoAction -> False,
Initialization :> (
errorFunction[v_, f_] := (
varlist = ToExpression[v];
funct = ToExpression[f];
varlength = Length[Variables[varlist]];
theoretical =
Sqrt[(Total[
Table[(D[funct, Part[varlist, n]]*
Subscript[U, Part[varlist, n]])^2, {n, 1,
varlength}]])];
Part[theoretical, 1];
varlist;
uncert = Table[Subscript[U, Part[varlist, n]], {n, 1, varlength}];
uncert = DeleteCases[uncert, Alternatives ## {0}];
theoretical = Simplify[theoretical];
Column[{Row[{Grid[{
{"Variables", varlist},
{"Uncertainties", uncert},
{"Function", function},
{"Uncertainty Function", theoretical}}, Alignment -> Left,
Spacings -> {2, 1}, Frame -> All,
ItemStyle -> {"Text", FontSize -> 20},
Background -> {{LightGray, None}}]}],
Row[{
Grid[{{"Brian Gennow March/24/2015"}}, Alignment -> Left,
Spacings -> {2, 1}, ItemStyle -> "Text",
Background -> {{None}}]
}]}]))]
This question was posted over 5 years ago, but I ran into the same issue recently and thought I'd share my solution (for uncorrelated errors).
I define a function errorProp that takes two arguments, func and vars. The first argument of errorProp, func, is the symbolic form of the expression for which you wish to calculate the error of its value due to the errors of its arguments. The second argument for errorProp should be a list of the form
{{x1,x1 value, dx1, dx1 value},{x2,x2 value, dx2, dx2 value}, ... ,
{xn,xn value, dxn, dxn value}}
Where the xi's and dxi's are the symbolic representations of the variables and their errors, while the xi value and dxi value are the numerical values of the variable and its uncertainty (see below for an example).
The function errorProp returns the symbolic form of the error, the value of the input function func, and the value of the error of func calculated from the inputs in vars. Here is the code:
ClearAll[errorProp];
errorProp[func_, vars_] := Module[{derivs=Table[0,{Length[vars]}],
funcErrorForm,funcEval,funcErrorEval,rplcVals,rplcErrors},
For[ii = 1, ii <= Length[vars], ii++,
derivs[[ii]] = D[func, vars[[ii, 1]]];
];
funcErrorForm = Sqrt[Sum[(derivs[[ii]]*vars[[ii, 3]])^2,{ii,Length[vars]}]];
SetAttributes[rplcVals, Listable];
rplcVals = Table[Evaluate[vars[[ii, 1]]] :> Evaluate[vars[[ii, 2]]], {ii,
Length[vars]}];
SetAttributes[rplcErrors, Listable];
rplcErrors = Table[Evaluate[vars[[ii, 3]]] :> Evaluate[vars[[ii, 4]]], {ii,
Length[vars]}];
funcEval = func /. rplcVals;
funcErrorEval = funcErrorForm /. rplcVals /. rplcErrors;
Return[{funcErrorForm, funcEval, funcErrorEval}];
];
Here I show an example of errorProp in action with a reasonably complicated function of two variables:
ClearAll[test];
test = Exp[Sqrt[1/y] - x/y];
errorProp[test, {{x, 0.3, dx, 0.005}, {y, 0.9, dy, 0.1}}]
returns
{Sqrt[dy^2 E^(2 Sqrt[1/y] - (2 x)/y) (-(1/2) (1/y)^(3/2) + x/y^2)^2 + (
dx^2 E^(2 Sqrt[1/y] - (2 x)/y))/y^2], 2.05599, 0.0457029}
Calculating using the error propagation formula returns the same result:
{Sqrt[(D[test, x]*dx)^2 + (D[test, y]*dy)^2],
test /. {x :> 0.3, dx :> 0.005, y :> 0.9, dy :> 0.1},
Sqrt[(D[test, x]*dx)^2 + (D[test, y]*dy)^2] /. {x :> 0.3,
dx :> 0.005, y :> 0.9, dy :> 0.1}}
returns
{Sqrt[dy^2 E^(
2 Sqrt[1/y] - (2 x)/y) (-(1/2) (1/y)^(3/2) + x/y^2)^2 + (
dx^2 E^(2 Sqrt[1/y] - (2 x)/y))/y^2], 2.05599, 0.0457029}
Mathematica 12 introduced the Around function that handles error propagation using the differential method.
So although not quite in the format required in the question, but something like this is possible:
expression = a^2*b;
expression /. {a -> Around[aval, da], b -> Around[bval, db]}
output:
aval^2 bval ± Sqrt[aval^4 db^2+4 bval^2 Abs[aval da]^2]
Instead of aval, bval, da, db you can use numerical values as well.
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]
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.