package labs;
import utils.Point;
import utils.Spline;
/*
* Spline interpolation of function
*/
public class Lab1 {
private static double function(double arg) {
return Math.sin(arg)*Math.cos(arg);
}
private static void printDiv(Spline[] splines, Point[] nodes){
for(Integer i = 0; i < splines.length; i++) {
System.out.println(" " + i.toString() + "\t" +
Double.toString(
Math.abs(
function(nodes[i].x) - splines[i].calc(nodes[i].x)
)));
}
if(splines.length != nodes.length)
System.out.println(" " + Integer.toString(splines.length).toString() + "\t" +
Double.toString(
Math.abs(
function(nodes[splines.length].x) - splines[splines.length-1].calc(nodes[splines.length].x)
)));
}
private static void print(Spline[] splines, Point[] nodes){
for(Integer i = 0; i < splines.length; i++) {
System.out.println(" " + i.toString() + "\t" +
Double.toString(function(nodes[i].x)) + "\t" +
Double.toString(splines[i].calc(nodes[i].x)));
}
if(splines.length != nodes.length)
System.out.println(" " + Integer.toString(splines.length) + "\t" +
Double.toString(function(nodes[splines.length].x)) + "\t" +
Double.toString(splines[splines.length-1].calc(nodes[splines.length].x)));
}
private static Spline[] progon(Point[] nodes, double h){
Spline[] splines = new Spline[nodes.length-1];
for(int i = 0; i < nodes.length-1; i++) splines[i] = new Spline();
for(int i = 0; i < splines.length; i++) {
splines[i].a = nodes[i].y;
}
double[] alpha = new double[splines.length];
double[] betta = new double[splines.length];
for(int i = 1; i < splines.length; i++) {
alpha[i] = (-1)/(alpha[i-1] + 4);
betta[i] = ((3*(nodes[i-1].y - 2*nodes[i].y + nodes[i+1].y))/(h*h) - betta[i-1])/(alpha[i-1] + 4);
}
splines[splines.length-1].c = ((3*(nodes[splines.length-2].y - 2*nodes[splines.length-1].y + nodes[splines.length].y))/(h*h) - betta[splines.length-1])/(4 + alpha[splines.length-1]);
for(int i = splines.length-2; i > 0; i--) {
splines[i].c = alpha[i+1]*splines[i+1].c + betta[i+1];
}
return splines;
}
public static void start(int steps) {
System.out.println("Steps: " + Integer.toString(steps));
double start = 0.0;
double finish = Math.PI / 2;
Point[] nodes = new Point[steps+1];
for(int i = 0; i < steps+1; i++) nodes[i] = new Point();
for(int i = 0; i <= steps; i++) {
nodes[i].x = ((finish - start)*i) / steps;
nodes[i].y = function(nodes[i].x);
}
Point[] mediansFunc = new Point[steps];
for(int i = 0; i < steps; i++) mediansFunc[i] = new Point();
for(int i = 0; i < steps; i++) {
mediansFunc[i].x = (nodes[i].x + nodes[i+1].x)/2;
mediansFunc[i].y = function(mediansFunc[i].x);
}
double h = (finish - start)/steps;
//fill A and C
Spline[] splines = progon(nodes, h);
//fill X
for(int i = 0; i < steps; i++) {
splines[i].x = nodes[i].x;
}
//fill D
for(int i = 0; i < steps; i++) {
splines[i].d = ( splines[ (i+1)%steps ].c - splines[i].c) / (3 * h);
}
//fill B
for(int i = 0; i < steps; i++) {
splines[i].b = (nodes[i+1].y - nodes[i].y)/h - (h/3)*(splines[(i+1)%steps].c + 2*splines[i].c);
}
print(splines, nodes);
System.out.println();
printDiv(splines, nodes);
System.out.println();
print(splines, mediansFunc);
System.out.println();
printDiv(splines, mediansFunc);
}
}