0

I wrote this code for my homework on MATLAB about cubic spline interpolation with a tridiagonal matrix. I follow all the steps of the algorithm and I really don't find my error. The code it's ok with second grade functions but when I put, for example, sin(x) the result is not a spline and don't know why because with the other function I have no problems. Can anyone help me to find the error? Thanks

CUBIC SPLINE SCRIPT:

close all
clear all
clf reset

ff = @(x) sin(x);
x = [-2 0 2 4 6 7 8 9 10 11 12];
for i = 1: length(x),
    omega(i) = ff(x(i));
end

n = length(x);
h = zeros(n - 1, 1);
for i = 1: n - 1,
    h(i) = x(i + 1) - x(i);
end

a = zeros(n, 1);
b = zeros(n, 1);
d = zeros(n, 1);
f = zeros(n, 1);

for j = 2: n - 1,
    a(j) = 2*(h(j) + h(j - 1));
    b(j) = h(j - 1);
    d(j) = h(j);
    f(j) = 6 * (omega(j + 1) - omega(j) / h(j)) - (6 * (omega(j) - omega(j - 1)) / h(j - 1));
end

% Starting conditions
a(1) = -2;
f(1) = 0;
a(n) = 4;
f(n) = 0;

% Coefficents
c = tridiag(a, b, d, f);

t = linspace (x(1), x(n), 301);
for k = 1: length(t),
    tk = t(k);
    y(k) = spline_aux(x, omega, c, tk);
    z(k) = ff(tk);
end

plot(t, z, 'b-', 'linewidth', 2)
hold on;
plot(t, y, 'r.', x, omega, 'go')
grid on

TRIADIAGONAL MATRIX:

function [x] = tridiag(a, b, d, f)

n = length(f);
alfa = zeros(n, 1);
beta = zeros(n, 1);

alfa(1) = a(1);
for i = 2: n,
    beta(i) = b(i) / alfa(i - 1);
    fprintf ('  i: %d     beta: %12.8f\n', i, beta(i))
    alfa(i) = a(i) - (beta(i)*d(i - 1));
    fprintf ('  i: %d     alfa: %12.8f\n', i, alfa(i))
end

y(1) = f(1);
for i = 2: n,
    y(i) = f(i) - beta(i)*y(i - 1);
end

x(n) = y(n) / alfa(n);
for i = n - 1: 1,
    x(i) = (y(i) - (d(i)*x(i + 1))) / alfa(i);
end

SPLINE EVALUATION IN tk POINT:

function [s] = spline_aux(x, w, c, tk)

n = length(x);

h = zeros(n - 1, 1);
for i = 1: n - 1,
    h(i) = x(i+1) - x(i);
end

 for i = 1: n - 1,
     if (x(i) <= tk && tk <= x(i+1))
        break
     end
 end

s1 = c(i)*((x(i+1) - tk)^3)/(6*h(i));
s2 = c(i+1)*((tk - x(i))^3)/(6*h(i));
s3 = (w(i)/h(i) - (c(i)*h(i)/6))*(x(i+1) - tk);
s4 = (w(i+1)/h(i) - (c(i+1)*h(i)/6))*(tk - x(i));
s = s1 + s2 + s3 + s4;
Snorfalorpagus
  • 3,348
  • 2
  • 29
  • 51
marks
  • 31
  • 9
  • The result is not a spline? Is it a bus ticket or a cake? My point: What are you getting? what do you expect to get? – Ander Biguri Nov 07 '14 at 10:04
  • I can't put the image because I have low reputation and I am new in this site, sorry. However yes it's not a spline. The resolution have to show the spline and I have to compare it with the function sin(x) changing the starting condition but the results are, between each point, straight line so the resolution it's not a spline and so I can't do the comparison requested.. I follow the algorithm but I didn't understand what miss for show the spline (without using MATLAB spline function but using my spline_aux).. Sorry if I wasn't clear – marks Nov 07 '14 at 11:34
  • Put the image somwhere and post a link. We will put the image in the post – Ander Biguri Nov 07 '14 at 11:37

1 Answers1

0

Thats because you are not using Matlab's for correctly

in the function function [x] = tridiag(a, b, d, f)

the last for reads for i = n - 1: 1 but that will never execute, you shoudl writte:

for i = n - 1:-1:1

Then works. You should notice that it didt work in ANY previous attempt, not only with sin(x)

enter image description here

Ander Biguri
  • 35,140
  • 11
  • 74
  • 120
  • I have tried with another second grade function and it gives me another error and I don't know why... Funcion: ff = @(x) 2*x*x - 3*x + 5; X values: x = [-6 -4 -2 0 2 3 5 7]; Result: http://imageshack.com/a/img909/1052/QKU1yX.jpg – marks Nov 11 '14 at 13:32
  • Sorry, I forget the starting condition: a(1) = -2; f(1) = 3; a(n) = 4; f(n) = 5; – marks Nov 11 '14 at 13:39
  • @marks Thats a completely different thing. You are not imposing smoothness between splines. You are just not doing that. You need to learn more about what you are doing and how! you need to formulate the spline equation so the first derivative on a point is constant in diferent adjacent splines. – Ander Biguri Nov 11 '14 at 15:27
  • @marks Additionally, read about how stackoverflow works. This is not a forum, you shoudl not Answer your question with anoder question. End this question, accept the answer if you liked it, and then create a new question with your specific prblem! ;) – Ander Biguri Nov 11 '14 at 15:28
  • 1
    I'm sorry, I did it without thinking. My fault, sorry. And thanks for your answers. – marks Nov 11 '14 at 15:33
  • Sorry, @Ander, but the problem is that maybe I don't understand what I have to do. My professor just told us to this code and make a comparison between the normal function and the spline (implemented by me) function and I expected that I will have the same result that you show me with sin(x) with another function, so I don't understand the point. My professor and my books are not clear, could yoy try to explain me why I can't have the result I am looking for with the function which I posted? I am a little confused – marks Nov 11 '14 at 15:45
  • @marks You are calculating piecewise splines to interpolate a set of data. The problem is that you are not telling the piecewise splines to be smooth in the points they "stick" together. Therefore, for complicated shapes, you dont have 1st order smoothness (wich I suppose is what you want). Therefore you need to create the esplines somehow else. I strongly suggest you have a look at this book: `Foley vanDam Feiner Hughes. Computer Graphics, principles and practice. Addison-Wesley, 2nd edition, 1990.` As it has a chapter explaining step by step how to create piecewise splines. good luck there! – Ander Biguri Nov 11 '14 at 15:48
  • 1
    Thank you so much @Ander I will try to examine in depth. Thanks again. – marks Nov 11 '14 at 15:53