1
$\begingroup$

enter image description here

ClearAll["Global`*"];
x1 = {1, 2, 3, 4};
y1 = {3, 4, 2, 5};
f = Factor[\!\(
\*UnderoverscriptBox[\(\[Sum]\), \(i = 1\), \(Length[x1]\)]\(\((
\*UnderoverscriptBox[\(\[Product]\), \(j = 1\), \(Length[x1]\)]\((If[
        j != i, 
\*FractionBox[\(x - x1[\([j]\)]\), \(x1[\([i]\)] - 
          x1[\([j]\)]\)]])\))\)*y1[\([i]\)]\)\)]

I don't have idea why that "Null" appear so, anyone can help me? (I'm an amateur)

$\endgroup$
  • 2
    $\begingroup$ Use the three-argument form of If ( If[ j != i, result1, result2]). With two-argument form If[j!=i,result] , If returns Null when j==i. $\endgroup$ – kglr Sep 5 at 4:42
  • 1
    $\begingroup$ Use Product[If[j!=i,term,1]...] which will insert either the term or a 1 into your product. And you can use the same trick using a zero when you are doing sums instead of products. $\endgroup$ – Bill Sep 5 at 4:47
1
$\begingroup$

It seems that you are trying to implement Lagrange interpolation. You can use Delete:

Clear[f]
f[pts_List, x_] := Module[{l, n = Length[pts], xys = pts\[Transpose]},
  (*define the interpolation function*)
  l[i_] := Product[(x - xys[[1, j]])/(xys[[1, i]] - xys[[1, j]]), {j, Delete[Range[n], i]}];
  (l /@ Range[n]).xys[[2]]
  ]

where the outer summation is implemented via Dot (.) in the last line. The code can be tested as

points = {{x0, y0}, {a, ya}, {b, yb}, {x1, y1}};
f[points, x]

In terms of your data, points = Transpose[{x1, y1}];. Actually, there is a built-in function doing the very same job: InterpolatingPolynomial.

$\endgroup$
1
$\begingroup$

The Null appears because two-argument If[] produces Null if the condition in the first argument is not satisfied. Αλέξανδρος shows one possibility, but you can fix your original code by recalling that $1$ is the identity element for multiplication; thus, you can implement Lagrangian interpolation like so:

With[{x1 = {1, 2, 3, 4}, y1 = {3, 4, 2, 5}}, 
     p1 = Sum[Indexed[y1, i]
              Product[If[i != j, (x - Indexed[x1, j])/(Indexed[x1, i] - Indexed[x1, j]), 1],
              {j, 1, Length[x1]}], {i, 1, Length[x1]}]];

Check:

Simplify[p1 == InterpolatingPolynomial[Transpose[{{1, 2, 3, 4}, {3, 4, 2, 5}}], x]]
   True

That being said, the classical version is not the best way to implement Lagrangian interpolation; in particular, one might consider instead using the so-called barycentric form:

With[{x1 = {1, 2, 3, 4}, y1 = {3, 4, 2, 5}},
     w = Table[1/Apply[Times, x1[[j]] - Delete[x1, j]], {j, 1, Length[x1]}];
     p2 = (w/(x - x1)).y1/Total[w/(x - x1)]];

Check:

Simplify[p2 == InterpolatingPolynomial[Transpose[{{1, 2, 3, 4}, {3, 4, 2, 5}}], x]]
   True

See the linked paper for more details.

$\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.