I have some problems in writing a module for spline smoothing. Actually, I have been trying for about two weeks. My listing is here:
SplSmooth[data_, knots_, lambda_, degree_] :=
Module[{M, Knots, NKnots, NBasis, X, Dsq, a},
M = Length@data;
Knots = Flatten@{Table[1, {i, 1, degree}], knots,Table[M, {i,1,degree}]};
NKnots = Length@Knots;
NBasis = NKnots - degree - 1;
X = Table[
Evaluate @ BSplineBasis[{degree, Knots}, n, t] // N, {t, 1, M},
{n, 0, NBasis - 1}];
Dsq = Differences[X, 2];
a=Inverse[Transpose[X].X + lambda*Transpose[Dsq].Dsq // N].Transpose[X].data // N;
Return[X.a]
];
When I try to place a knot in every point in my data, numerical errors arise, such as:
Inverse::luc: Result for Inverse of badly conditioned matrix {{1.251,-0.1255,-0.251,0.0836667,0.0418333,0.,0.,0.,0.,0.,<<72>>},<<9>>,<<72>>} may contain significant numerical errors. >>
Obviously, the corresponding result is wrong (I can see it from the plot). It seems that the matrix to be inverted is ill-conditioned:
a = Inverse[Transpose[X].X + lambda*Transpose[Dsq].Dsq // N].Transpose[X].data // N;
but now comes the other problem. I use equidistant knots (let's say with 7 points distance) to overcome this problem. But then sometimes the algorithm works with:
Knots = Flatten @ {Table[1, {i, 1, degree}], knots, Table[M, {i, 1, degree}]};
and some other times works with
Knots = Flatten @ {Table[1, {i, 0, degree}], knots, Table[M, {i ,0, degree}]};
Now, I think that there is some kind of problem in BSplineBasis
function.
Q: Can you spot the problem please? Or has anyone of you implemented a simillar function in the past with BSplineBasis
function?
Inverse
when you can useLinearSolve
. Solving a linear system is much faster and stabler than calculating an inverse. $\endgroup$