Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have some lists of interpolated functions and I want to know if there is an easy way to operate with them. A simplified example:

listsin = Table[FunctionInterpolation[Sin[i*x], {x, 0, 2 Pi}], {i, 1, 10}]
listlinear = Table[FunctionInterpolation[i*x, {x, 0, 2 Pi}], {i, 1, 10}]

This generates two lists of ten functions each. I want to be able to perform basic operations with these functions: sums, derivatives and products. I came up with a way that works

listsumd = Table[With[{i = i}, (listsin[[i]]'[#] + listlinear[[i]]'[#]) &], {i, 1, 10}]

But want to know if it is possible to do this without having to iterate through all the elements in the table, just by operating directly on the lists.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

I'm not sure of the output that you want but this returns a list if functions that should be equivalent to those in your listsumd:

MapThread[{##} /. {sin_, lin_} :> (sin'[#] + lin'[#] &) &, {listsin, listlinear}]

Please see Mathematica Destructuring regarding the code {##} /. {sin_, lin_} :>.


You commented that this is slower than your own code. It is because your code evaluates each Function body to a lesser degree. The output from your code includes e.g. listsin[[1]] (and is dependent on the external definition of listsin) whereas the output from mine includes explicit InterpolatingFunction expressions. I realize now evaluation could be taken a step further: evaluation of the derivatives. This would be slower still in generation, but should be faster in repeated application as it is only done once. Code for the greater evaluation:

MapThread[{#', #2'} /. {sin_, lin_} :> (sin[#] + lin[#] &) &, {listsin, listlinear}]

Also, here is a way to write both forms using Inner and nested Function expressions, just to show alternatives. First without evaluating the derivatives:

Inner[Function[{sin, lin}, sin'[#] + lin'[#] &], listsin, listlinear, List]

And with:

Inner[Function[{sin, lin}, sin[#] + lin[#] &][#', #2'] &, listsin, listlinear, List]
share|improve this answer
    
Yes, that's the output i wanted, I like the MapThread idea, making the code more concise. However, I checked the timing and it seems doing it element by element is faster (not that it matters when it takes .01 seconds). I also wanted to ask if you know, if it is better to work with lists of functions or with functions over lists (in terms of speed, and code legibility) –  Noel Perez Gonzalez Mar 14 at 13:41
    
@Noel Please see my updated answer regarding your first point. Regarding your second I would need to see a larger example of your actual application to make a good recommendation. –  Mr.Wizard Mar 14 at 14:01
    
an example of a list of functions would be a = Table[With[{i = i}, N[Sin[i*#]] &], {i, 1, 10}] (each element on the list is a function) and a function over a list would be b = Table[With[{i = i}, N[Sin[i*#]]], {i, 1, 10}] & (it is a function that returns a list of values). They are conceptually equal (a[[i]][x]==b[x][[i]]). Now, if i wanted to perform a calculation, say, compute an integral over x for a given element i, would there be any difference between those two approaches? –  Noel Perez Gonzalez Mar 14 at 15:19

Just an alternative (using definitions listsin,listlinear):

f[x_] := Total /@ Map[#'[x] &, Transpose[{listsin, listlinear}], {2}]

or (to produce pure function as per Mr. Wizard):

g=(Total /@ 
    Map[Function[g, g'[#]], Transpose[{listsin, listlinear}], {2}]) &;

Testing:

Through[MapThread[{##} /. {sin_, 
       lin_} :> (sin'[#] + lin'[#] &) &, {listsin, listlinear}][3]]

{0.0100104, 3.92033, 0.266653, 7.37543, 1.20151, 9.96203, 3.16562, \ 11.3939, 6.3699, 11.5439}

Similarly f[3] gives:>

{0.0100104, 3.92033, 0.266653, 7.37543, 1.20151, 9.96203, 3.16562, \ 11.3939, 6.3699, 11.5439} and g[3]:

{0.0100104, 3.92033, 0.266653, 7.37543, 1.20151, 9.96203, 3.16562, \ 11.3939, 6.3699, 11.5439}

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.