1

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.

Noel
  • 291
  • 1
  • 7

2 Answers2

2

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]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • 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 Mar 14 '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 '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 Mar 14 '14 at 15:19
0

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}

ubpdqn
  • 60,617
  • 3
  • 59
  • 148