# Combining "Product" and "If" 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)

• 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.
– kglr
Sep 5 '19 at 4:42
• 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.
– Bill
Sep 5 '19 at 4:47

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[]
]


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.

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.