开发者

How to have a variable argument list in Mathematica

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开发者_如何学C 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜