1
$\begingroup$

This problem is mentioned in my self-answer here.

Here is an illustration of the problem:

f1 = ListInterpolation[Array[a, 10]];
f2 = ListInterpolation[Array[a, 10], {{1, 10}}];
f3 = ListInterpolation[Array[a, 10], {{1., 10.}}];
f1 === f2
f2 === f3
(* True *)
(* False *)

InputForm[f1]
InterpolatingFunction[{{1, 10}}, {5, 3, 0, {10},
{4}, 0, 0, 0, 0, Automatic, {}, {}, False},
{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, 
{{a[1]}, {a[2]}, {a[3]}, {a[4]}, {a[5]}, {a[6]}, {a[7]}, {a[8]}, {a[9]}, {a[10]}},
{Automatic}]
InputForm[f3]
InterpolatingFunction[{{1., 10.}}, {5, 3, 0, {10},
{4}, 0, 0, 0, 0, Automatic, {}, {}, False},
{{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}},
{{a[1.]}, {a[2.]}, {a[3.]}, {a[4.]}, {a[5.]}, {a[6.]}, {a[7.]}, {a[8.]}, {a[9.]}, {a[10.]}},
{Automatic}]

Note how the values are stored in each InterpolatingFunction - a list of a[i]. Except, as soon as we introduced a real domain ({1., 10.}) instead of integer ({1, 10}), ListInterpolation converted the integer indices of a to real values.

Now I cannot do this:

Evaluate[Array[a, 10]] = RandomReal[10, {10}];
Plot[f3[x],{x,1,10}] (* returns empty plot *)

However this works:

Plot[{f1[x],f2[x]},{x,1,10}]
(* returns a random curve through 10 points, as it should *)

I know, how to fix this, a solution is mentioned in my answer.

Question: is this a bug? Or are there reasons for this behavior? Do note, that not all integers are converted to reals, but I see no reason for the indices to be affected. Could it be applying N to the list of values?

$\endgroup$
  • $\begingroup$ It seems you are right: N is applied internally in the case of f3. You can protect indices by setting the NHoldAll for a: SetAttributes[a, NHoldAll]. $\endgroup$ – Alexey Popkov Feb 22 '16 at 9:45
  • $\begingroup$ @AlexeyPopkov I'm not sure about ListInterpolation, but Interpolation does support interpolation of symbolic values. Thanks for referencing NHoldAll, that's a much cleaner way to work around this. $\endgroup$ – LLlAMnYP Feb 22 '16 at 9:49
  • $\begingroup$ I would file this under "expected behavior" - it assumes that since the interpolating function takes real-valued input that it would give real-valued output. You can replace Array[a, 10] by Range[10] in the post to make it more clear what is going on. $\endgroup$ – Jason B. Feb 22 '16 at 9:49
  • $\begingroup$ @JasonB I think, if I replace Array[a, 10] with Range[10], this behavior becomes not only expected, but also desirable. Machine-precision computation is faster, and if the domain is to machine-precision, the interpolation ought to follow suit as well. I think, Alexey nailed the correct approach. $\endgroup$ – LLlAMnYP Feb 22 '16 at 9:53
  • $\begingroup$ Note that the same thing happens with Interpolation: Interpolation[Array[{N@#, a@#} &, 10]] // InputForm. From this observation I suspect that it is a bug: the developer simply forgot to add a check for symbolic values of the function before applying N to them. Just a bit careless implementation, not the intended behavior. $\endgroup$ – Alexey Popkov Feb 22 '16 at 10:02
1
$\begingroup$

N is indeed applied internally, when the interpolation is carried out to machine-precision, rather than arbitrary precision. This can be explicitly tested by the following:

Clear[a];
a /: N[a[x_Integer]] := (Print["N(a)"]; a[N@x])
ListInterpolation[Array[a, 10], {{1., 10.}}]

N(a)
N(a)
N(a)
N(a)
N(a)
N(a)
N(a)
N(a)
N(a)
N(a)

 InterpolatingFunction[...]

This behavior has clear reasons. If the interpolation is done to machine-precision, rather than arbitrary precision, it makes no sense to leave the values at arbitrary precision. However, because N is rather aggressive in its listability, the correct approach is to protect the indices of the array by applying the attribute NHoldAll (rather than my workaround of a[idx__Real] := a @@ (Floor /@ {idx});).

SetAttributes[a, NHoldAll]
ListInterpolation[Array[a, 10], {{1., 10.}}] // InputForm
InterpolatingFunction[{{1., 10.}}, {5, 3, 0, {10},
{4}, 0, 0, 0, 0, Automatic, {}, {}, False},
{{1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}},
{{a[1]}, {a[2]}, {a[3]}, {a[4]}, {a[5]}, {a[6]}, {a[7]}, {a[8]}, {a[9]}, {a[10]}},
{Automatic}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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