5

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.

4
  • The problem is in getY. Since, getX only "understands" two variables, the expression getX[x] within getY will have problems. So, you need to define what you expect to get from applying getY to more than 2 variables, then you can determine what role getX must play. For instance, given the list, {a,b,c}, is each term in the sum dependent on successive terms in the list, i.e. should you be summing over {{a,b},{b,c}}? Commented Apr 21, 2011 at 17:17
  • @rcollyer each term is independent of successive terms. I'm not sure what you mean by "applying getY to more than 2 variables"? Commented Apr 21, 2011 at 17:24
  • I think it will be much easier to help if you post your math. Commented Apr 21, 2011 at 17:24
  • 1
    I see it isn't relevant with your data, but what I meant was getY[a,b,c] would result in getX[a,b,c] which isn't evaluated as it isn't defined, which is the key to why your code is not evaluating correctly. I'd say more, but Sasha beat me to it. Commented Apr 21, 2011 at 17:47

2 Answers 2

5

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}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer, but it's not quite working for me yet. I'll update the question.
@belisarius I'm sure it's not working, but I'm also sure I'm doing something stupid, haha. I'm still trying to isolate the problem, doing simple tests give exactly what I want
Perhaps you need BlankNullSequence ? See reference.wolfram.com/mathematica/ref/BlankNullSequence.html
@wrong, could you post the code that is not working, as an update to your question? It will help in diagnosing what's wrong.
@rcollyer and @belisarius, I've posted it!
3

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.

3 Comments

Thanks so much for the solutions! Is there some documentation to explain the various symbols you used?
"does not know which signature of getX to use", and hence it is left unevaluated until after it has been given numeric values. At which point, lacking any variables, the derivative is 0.
@wrongusername Mathematica comes with full editable documentation. Select the symbol you would like to look up, and use menu Help > "Find Selected Function". For instance both @@ and @@@ would lead you to Apply. & is a shortcut for Function, ## is SlotSequence. ;; is Span. Mathematica code written using these symbols is sometimes referred to as "runic code". I, personally, think pieces of runic Mathematica are worth displaying on t-shirts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.