Algorithm in C to calculate coefficients of polynomial using Lagrange interpolation - c

I've been stuck on this for a while now. I'm writing an algorithm in C to pull out the coefficients of a polynomial using Lagrange's interpolation method.
My code partially works, for instance if we do the first example here http://en.wikipedia.org/wiki/Lagrange_polynomial#Example_1 then the code can print out the first 2 coefficients (0 and 4.834848)
Similarly with example 3 on that article, it will print the 2 coefficients 6 and -11.
I need to be able to accurately get all the coefficients from any set of points. Please advise on the alterations required to the code.
Thanks in advance!
Updated with latest code, 7:57PM, GMT on August 5th. 9 coefficients now working, getting ugly looking. Will investigate iterative process for n degrees tomorrow!
#include<ncursesw/ncurses.h>
#include<math.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define MAX 200
float coeff[MAX], coefftwo[MAX], coeffthree[MAX], coefffour[MAX];
int count;
void main()
{
int n,i,j ;
char ch;
float x[MAX],y[MAX],fp2, coeff1, coeff2;
printf("\n\nn = ");
scanf("%i", &count);
for(i=0; i < count; i++)
{
printf("\n\n The value of x%i= ", i);
scanf("%f",&x[i]);
printf("\n The value of f(x%i)= ", i);
scanf("%f",&y[i]);
}
for(i=0;i<count;i++)
{
coeff1 = 1.0;
coeff2 = 0.0;
coeff3 = 0.0;
coeff4 = 0.0;
coeff5 = 0.0;
coeff6 = 0.0;
coeff7 = 0.0;
coeff8 = 0.0;
coeff9 = 0.0;
for(j=0; j<count; j++)
{
if(i!=j) {
coeff1 = coeff1 * (array[i]-array[j]);
coeff2 -= array[j];
for (int k=j; k < count; k++) {
if ((j!=k) && (k!=i)) {
coeff3 += array[j] * array[k];
for(int l=k; l < count; l++) {
if ((l!=j) && (l!=k) && (l!=i)) {
coeff4 -= array[j] * array[k] * array[l];
for (int m = l; m < count; m++) {
if ((m!=l) && (m!=k) && (m!=j) && (m!=i)) { coeff5 += array[j] * array[k] * array[l] * array[m];
for (int n = m; n < count; n++) {
if ((n!=m) && (n!=l) && (n!=k) && (n!=j) && (n!=i)) {
coeff6 -= array[j] * array[k] * array[l] * array[m] * array[n];
for (int o = n; o < count; o++) {
if ((o!=n) && (o!=m) && (o!=l) && (o!=k) && (o!=j) && (o!=i)) {
coeff7 += array[j] * array[k] * array[l] * array[m] * array[n] * array[o];
for (int p = o; p < count; p++) {
if ((p!=o) && (p!=n) && (p!=m) && (p!=l) && (p!=k) && (p!=j) && (p!=i)) {
coeff8 -= array[j] * array[k] * array[l] *array[m] *array[n] * array[o] * array[p];
for (int q = p; q < count; q++) {
if ((q!=p) && (q!=o) && (q!=n) && (q!=m) && (q!=l) && (q!=k) && (q!=j) && (q!=i)) {
coeff9 += array[j] * array[k] * array[l] * array[m] * array[n] * array[o] * array[p] * array[q];
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
coeff[i] = y[i] / coeff1;
coefftwo[i] = y[i] * coeff2 / coeff1;
coeffthree[i] = y[i] * coeff3 / coeff1;
coefffour[i] = y[i] * coeff4 / coeff1;
coefffive[i] = y[i] * coeff5 / coeff1;
coeffsix[i] = y[i] * coeff6 / coeff1;
coeffseven[i] = y[i] * coeff7 / coeff1;
coeffeight[i] = y[i] * coeff8 / coeff1;
coeffnine[i] = y[i] * coeff9 / coeff1;
}
float coefficientone = 0.0;
float coefficienttwo = 0.0;
float coefficientthree = 0.0;
float coefficientfour = 0.0;
float coefficientfive = 0.0;
float coefficientsix = 0.0;
float coefficientseven = 0.0;
float coefficienteight = 0.0;
float coefficientnine = 0.0;
for (int i = 0; i< count; i++){
coefficientone = coefficientone + coeff[i];
coefficienttwo = coefficienttwo + coefftwo[i];
coefficientthree = coefficientthree + coeffthree[i];
coefficientfour = coefficientfour + coefffour[i];
coefficientfive = coefficientfive + coefffive[i];
coefficientsix = coefficientsix + coeffsix[i];
coefficientseven = coefficientseven + coeffseven[i];
coefficienteight = coefficienteight + coeffeight[i];
coefficientnine = coefficientnine + coeffnine[i];
}
printf("coefficient 1 = %f\n", coefficientone);
printf("coefficient 2 = %f\n", coefficienttwo);
printf("coefficient 3 = %f\n", coefficientthree);
printf("coefficient 4 = %f\n", coefficientfour);
printf("coefficient 5 = %f\n", coefficientfive);
printf("coefficient 6 = %f\n", coefficientsix);
printf("coefficient 7 = %f\n", coefficientseven);
printf("coefficient 8 = %f\n", coefficienteight);
printf("coefficient 9 = %f\n", coefficientnine);
}

Your algebra is simply wrong, and that fact is hidden by poorly chosen variable names.
When you calculate the contribution of the ith basis polynomial (never mind y for now) what variable represents the coefficient of the x2 term? It's coeff3. And you don't calculate it correctly.
Take a simpler case. Suppose you want to work out (x+a)(x+b)(x+c)(x+d). The first term is x4, easy. The next is (a+b+c+d)x3, not too bad. The next is (ab + ac + ad + bc + bd + cd)x2, and now it's clear that a single loop won't do the job. It's worth taking the time to make sure you can write code that handles the simple problem correctly, before you try the more complex one. You need something like this:
for(unsigned int j=0 ; j<count ; ++j)
{
...
coeff2 -= x[j];
for(unsigned int k=j ; k<count ; ++k)
{
if(j!=k && k!=i)
coeff3 += x[j] * x[k];
...
}
}
That should be enough to get you started.

Related

As a result of processing arrays -nan(ind)

I am writing a program that creates arrays of a given length and manipulates them. You cannot use other libraries.
First, an array M1 of length N is formed, after which an array M2 of length N is formed/2.
In the M1 array, the division by Pi operation is applied to each element, followed by elevation to the third power.
Then, in the M2 array, each element is alternately added to the previous one, and the tangent modulus operation is applied to the result of addition.
After that, exponentiation is applied to all elements of the M1 and M2 array with the same indexes and the resulting array is sorted by dwarf sorting.
And at the end, the sum of the sines of the elements of the M2 array is calculated, which, when divided by the minimum non-zero element of the M2 array, give an even number.
The problem is that the result X gives is -nan(ind). I can't figure out exactly where the error is.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
const int A = 441;
const double PI = 3.1415926535897931159979635;
inline void dwarf_sort(double* array, int size) {
size_t i = 1;
while (i < size) {
if (i == 0) {
i = 1;
}
if (array[i - 1] <= array[i]) {
++i;
}
else
{
long tmp = array[i];
array[i] = array[i - 1];
array[i - 1] = tmp;
--i;
}
}
}
inline double reduce(double* array, int size) {
size_t i;
double min = RAND_MAX, sum = 0;
for (i = 0; i < size; ++i) {
if (array[i] < min && array[i] != 0) {
min = array[i];
}
}
for (i = 0; i < size; ++i) {
if ((int)(array[i] / min) % 2 == 0) {
sum += sin(array[i]);
}
}
return sum;
}
int main(int argc, char* argv[])
{
int i, N, j;
double* M1 = NULL, * M2 = NULL, * M2_copy = NULL;
double X;
unsigned int seed = 0;
N = atoi(argv[1]); /* N равен первому параметру командной строки */
M1 = malloc(N * sizeof(double));
M2 = malloc(N / 2 * sizeof(double));
M2_copy = malloc(N / 2 * sizeof(double));
for (i = 0; i < 100; i++)
{
seed = i;
srand(i);
/*generate*/
for (j = 0; j < N; ++j) {
M1[j] = (rand_r(&seed) % A) + 1;
}
for (j = 0; j < N / 2; ++j) {
M2[j] = (rand_r(&seed) % (10 * A)) + 1;
}
/*map*/
for (j = 0; j < N; ++j)
{
M1[j] = pow(M1[j] / PI, 3);
}
for (j = 0; j < N / 2; ++j) {
M2_copy[j] = M2[j];
}
M2[0] = fabs(tan(M2_copy[0]));
for (j = 0; j < N / 2; ++j) {
M2[j] = fabs(tan(M2[j] + M2_copy[j]));
}
/*merge*/
for (j = 0; j < N / 2; ++j) {
M2[j] = pow(M1[j], M2[j]);
}
/*sort*/
dwarf_sort(M2, N / 2);
/*sort*/
X = reduce(M2, N / 2);
}
printf("\nN=%d.\n", N);
printf("X=%f\n", X);
return 0;
}
Knowledgeable people, does anyone see where my mistake is? I think I'm putting the wrong data types to the variables, but I still can't solve the problem.
Replace the /* merge */ part with this:
/*merge*/
for (j = 0; j < N / 2; ++j) {
printf("%f %f ", M1[j], M2[j]);
M2[j] = pow(M1[j], M2[j]);
printf("%f\n", M2[j]);
}
This will print the values and the results of the pow operation. You'll see that some of these values are huge resulting in an capacity overflow of double.
Something like pow(593419.97, 31.80) will not end well.

How to matrix inversion For 1 Dimension with c code?

hello i used gauss jordan for 1d but i didnt
i want to find 1d matrix inverse. I found determinant but i dont know inverse of this matrix
Hello my dear friends
Our matrixes:
double A[] = {6, 6 ,2, 4, 9 ,7, 4, 3 ,3};
double B[] = {6, 6 ,2, 4, 9 ,7, 4, 3 ,3};
double Final[9];
Function to calculate determinant:
int Inverse(double *A, double *C, int N){
int n = N;
int i, j, k;
float a[10][10] = { 0.0 };
double C[9] = { 0.0 };
float pivot = 0.0;
float factor = 0.0;
double sum = 0.0; ``` variables
for (k = 1; k <= n - 1; k++)
{
if (a[k][k] == 0.0)
{
printf("error");
}
else
{
pivot = a[k][k];
for (j = k; j <= n + 1; j++)
a[k][j] = a[k][j] / pivot;
for (i = k + 1; i <= n; i++)
{
factor = a[i][k];
for (j = k; j <= n + 1; j++)
{
a[i][j] = a[i][j] - factor * a[k][j];
}
}
}
if (a[n][n] == 0)
printf("error");
else
{
C[n] = a[n][n + 1] / a[n][n];
for (i = n - 1; i >= 1; i--)
{
sum = 0.0;
for (j = i + 1; j <= n; j++)
sum = sum + a[i][j] * C[j];
C[i] = (a[i][n + 1] - sum) / a[i][i];
}
}
}
for (i = 1; i <= n; i++)
{
printf("\n\tx[%1d]=%10.4f", i, C[i]);
}
system("PAUSE");
return 0;
}
Although I tried very hard, I couldn't find the opposite in c programming for a 1x1 dimensional matrix. Output always generates 0. Can you help me where I could be making a mistake. Thank you.
It appears you are using C as an output parameter (to store the inverse); however, you also declare a local variable of the same name in the function. This causes the local variable to shadow (i.e.: hide) the output parameter; thus, changes you make to the C in the function do not affect the C the calling function sees.
To fix this issue, you need to remove the line double C[9] = {0}; from your function.

problem calculating the inverse of a matrix

I'm trying to calculate the inverse of a square matrix of any rank N x N. I'm using a struct to store the values of the matrix which I can to effectively and I am already able to calculate the determinant. But there must be some issue with the inverse function. This is the code
struct m{
size_t row;
size_t col;
double *data;
};
void inverse(size_t n, struct m *A) /*Calculate the inverse of A */
{
size_t i,j,i_count,j_count, count=0;
double det = determinant(n, A);
size_t id = 0;
double *d;
struct m C; /*The Adjoint matrix */
C.data = malloc(sizeof(double) * n * n);
C.row = n;
C.col = n;
struct m *minor; /*matrices obtained by removing the i row and j column*/
if (!(minor = malloc(n*n*(n+1)*sizeof *minor))) {
perror ("malloc-minor");
exit(-1);
}
if (det == 0){
printf("The matrix is singular\n");
exit(1);
}
for(id=0; id < n*n; id++){
d = minor[id].data = malloc(sizeof(double) * (n-1) * (n-1));
for(count=0; count < n; count++)
{
//Creating array of Minors
i_count = 0;
for(i = 0; i < n; i++)
{
j_count=0;
for(j = 0; j < n; j++)
{
if(j == count)
continue; // don't copy the minor column element
*d = A->data[i * A->col + j];
d++;
j_count++;
}
i_count++;
}
}
}
for(id=0; id < n*n; id++){
for(i=0; i < n; i++){
for(j=0; j < n; j++)
C.data[i * C.col + j] = determinant(n-1,&minor[id]);//Recursive call
}
}
transpose(&C);
scalar_product(1/det, &C);
*A = C;
}
The determinant is calculated recursively with this algorithm:
double determinant(size_t n, struct m *A)
{
size_t i,j,i_count,j_count, count=0;
double det = 0;
if(n < 1)
{
printf("Error\n");
exit(1);
}
if(n==1) return A->data[0];
else if(n==2) return (A->data[0]* A->data[1 * A->col + 1] - A->data[0 + 1] * A->data[1*A->col + 0]);
else{
struct m C;
C.row = A->row-1;
C.col = A->col-1;
C.data = malloc(sizeof(double) * (A->row-1) * (A->col-1));
for(count=0; count < n; count++)
{
//Creating array of Minors
i_count = 0;
for(i = 1; i < n; i++)
{
j_count=0;
for(j = 0; j < n; j++)
{
if(j == count)
continue; // don't copy the minor column element
C.data[i_count * C.col + j_count] = A->data[i * A->col + j];
j_count++;
}
i_count++;
}
det += pow(-1, count) * A->data[count] * determinant(n-1,&C);//Recursive call
}
free(C.data);
return det;
}
}
You can find the complete code here: https://ideone.com/gQRwVu.
Use some other variable in the loop after :
det + =pow(-1,count) * A->data[count] *determinant (n-1,&C)
Your calculation of the inverse doesn't quite correspond to the algorithm described e. g. for Inverse of a Matrix
using Minors, Cofactors and Adjugate, even taken into account that you for now omitted the adjugate and division step. Compare your outermost for loop in inverse() to this working implementation:
double Rdata[(n-1)*(n-1)]; // remaining data values
struct m R = { n-1, n-1, Rdata }; // matrix structure for them
for (count = 0; count < n*n; count++) // Create n*n Matrix of Minors
{
int row = count/n, col = count%n;
for (i_count = i = 0; i < n; i++)
if (i != row) // don't copy the current row
{
for (j_count = j = 0; j < n; j++)
if (j != col) // don't copy the current column
Rdata[i_count*R.col+j_count++] = A->data[i*A->col+j];
i_count++;
}
// transpose by swapping row and column
C.data[col*C.col+row] = pow(-1, row&1 ^ col&1) * determinant(n-1, &R) / det;
}
It yields for the given input data the correct inverse matrix
1 2 -4.5
0 -1 1.5
0 0 0.5
(already transposed and divided by the determinant of the original matrix).
Minor notes:
The *A = C; at the end of inverse() loses the original data pointer of *A.
The formatting function f() is wrong for negative values, since the fraction is also negative in this case. You could write if (fabs(f)<.00001).

Triangulation algorithm

I've decided to create a simple demo, dividing a polygon into triangle set. Here what i've got so far:
A sequential vertex list is given (P1) forming polygon edges (polygon is not convex in most cases); a triangle set is needed
Loop through all the vertices within the polygon P1 and find the one (v), which will satisfy next clauses:
remove v from polygon and save the new one to P2 previous vertex to v
connected to its next one form a
line which do not cross any of P2
edges
v is not inside P2
If these are satisfied, we can replace P1 with (P2 + triangle( prev(v), v, next(v)) ) and repeat this action until P1 contains more than 3 vertices.
So, the questions are: is this algorithm correct and how it could be implemented using C / C++ using the most obvious and simple way?
I think you're describing the ear clipping method. There's code for that method at http://cs.smith.edu/~orourke/books/ftp.html ; it's the code described in the book Computational Geometry in C.
Seems that i'm done with this algorithm implementation. Please, verify it someone. Thanks!
typedef struct Point
{
float x, y;
};
class MooPolygon
{
private:
vector<Point> points;
int isVertexEar(int n, const vector<Point> &p)
{
return (isVertexInsideNewPoly(n, p) && !isEdgeIntersect(n, p));
}
int isEdgeIntersect(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 0, cnt = a.size(), prev = (cnt + (n - 1)) % cnt, next = n % cnt;
Point v1 = a[prev], v2 = a[next];
for (size_t i = 0, j = cnt - 1; i < cnt; j = i++)
{
if (prev == i || prev == j || next == i || next == j)
continue;
Point v4 = a[j], v3 = a[i];
float denominator = ((v4.y - v3.y) * (v2.x - v1.x)) - ((v4.x - v3.x) * (v2.y - v1.y));
if (!denominator)
continue;
float ua = (((v4.x - v3.x) * (v1.y - v3.y)) - ((v4.y - v3.y) * (v1.x - v3.x))) / denominator;
float ub = (((v2.x - v1.x) * (v1.y - v3.y)) - ((v2.y - v1.y) * (v1.x - v3.x))) / denominator;
//float x = v1.x + (ua * (v2.x - v1.x)), y = v1.y + (ua * (v2.y - v1.y));
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
{
c = 1;
break;
}
}
return c;
}
int isVertexInsideNewPoly(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 1;
for (size_t i = 0, j = a.size() - 1; i < a.size(); j = i++)
{
if ((((a[i].y <= v.y) && (v.y < a[j].y)) || ((a[j].y <= v.y) && (v.y < a[i].y))) && (v.x > (a[j].x - a[i].x) * (v.y - a[i].y) / (a[j].y - a[i].y) + a[i].x))
c = !c;
}
return c;
}
float dist(Point a, Point b)
{
return sqrt( ((a.x - b.x) * (a.x - b.x)) + (((a.y - b.y) * (a.y - b.y))) );
}
public:
void push(const Point &p)
{
for (size_t i = 0; i < points.size(); i++)
{
if (dist(points[i], p) < 7.f)
{
points.push_back(points[i]);
return;
}
}
points.push_back(p);
}
void pop()
{
if (points.size() > 0)
points.pop_back();
}
void clear()
{
points.clear();
}
Point v(int index)
{
return points[index];
}
size_t size()
{
return points.size();
}
void triangulate()
{
vector<Point> a;
for (size_t i = 0; i < points.size(); i++)
{
a.push_back(points[i]);
}
points.clear();
for (size_t t = a.size() - 1, i = 0, j = 1; i < a.size(); t = i++, j = (i + 1) % a.size())
{
if (a.size() == 3)
{
points.push_back(a[0]);
points.push_back(a[1]);
points.push_back(a[2]);
break;
}
if (isVertexEar(i, a))
{
points.push_back(a[t]);
points.push_back(a[i]);
points.push_back(a[j]);
a.erase(a.begin() + i, a.begin() + i + 1);
t = a.size() - 1;
i = 0;
j = 1;
}
}
}
};
The code has an error on the line below. The line is in the for loop in the push() function of your class:
points.push_back(points[i]);
You are not passing the pushed Point, but an empty element of the vector itself. I changed the line to
points.push_back(p);
and it worked.

Newton method implementation for finding initial values, with Dormand Prince to solve differential equations in C

The following code works like a charm to solve a system of differential equations in it(fcn function in the code), with correct initial values. However, the point of the task is to replace initial values y_1(0) and y_2(0) with some random values, and implement some iterative method to find the correct initial values to solve the equation. I already know how to check if the value is correct value, since by definition output of ddopri 5 should give y_2(1) and y_3(1) as 0. How do I implement Newton Raphson for this problem?
#include<stdio.h>
#include<math.h>
#include<stdbool.h>
double ddopri5(void fcn(double, double *, double *), double *y);
double alpha;
void fcn(double t, double *y, double *f);
double eps;
int main(void){
double y[4];
//eps = 1.e-9;
printf("Enter alpha:\n");
scanf("%lg", &alpha);
printf("Enter epsilon:\n");
scanf("%lg", &eps);
y[0]=1.0;//x1(0)
y[1]=-1.22565282791;//x2(0)
y[2]=-0.274772807644;//p1(0)
y[3]=0.0;//p2(0)
ddopri5(fcn, y);
}
void fcn(double t, double *y, double *f){
/* double h = 0.25;*/
f[0] = y[1];
f[1] = y[3] - sqrt(2)*y[0]*exp(-alpha*t);
f[2] = sqrt(2)*y[3]*exp(-alpha*t) + y[0];
f[3] = -y[2];
}
double ddopri5(void fcn(double, double *, double *), double *y){
double t, h, a, b, tw, chi;
double w[4], k1[4], k2[4], k3[4], k4[4], k5[4], k6[4], k7[4], err[4], dy[4];
int i;
double errabs;
int iteration;
iteration = 0;
//eps = 1.e-9;
h = 0.1;
a = 0.0;
b = 1;//3.1415926535;
t = a;
while(t < b -eps){
printf("%lg\n", eps);
fcn(t, y, k1);
tw = t+ (1.0/5.0)*h;
for(i = 0; i < 4; i++){
/*printf("k1[%i] = %.15lf \n", i, k1[i]);*/
w[i] = y[i] + h*(1.0/5.0)*k1[i];
}
fcn(tw, w, k2);
tw = t+ (3.0/10.0)*h;
for(i = 0; i < 4; i++){
/*printf("k2[%i] = %.15lf \n", i, k2[i]);*/
w[i] = y[i] + h*((3.0/40.0)*k1[i] + (9.0/40.0)*k2[i]);
}
fcn(tw, w, k3);
tw = t+ (4.0/5.0)*h;
for(i = 0; i < 4; i++){
/*printf("k3[%i] = %.15lf \n", i, k3[i]);*/
w[i] = y[i] + h*((44.0/45.0)*k1[i] - (56.0/15.0)*k2[i] + (32.0/9.0)*k3[i]);
}
fcn(tw, w, k4);
tw = t+ (8.0/9.0)*h;
for(i = 0; i < 4; i++){
/*printf("k4[%i] = %.15lf \n", i, k4[i]);*/
w[i] = y[i] + h*((19372.0/6561.0)*k1[i] - (25360.0/2187.0)*k2[i] + (64448.0/6561.0)*k3[i] - (212.0/729.0)*k4[i]);
}
fcn(tw, w, k5);
tw = t + h;
for(i = 0; i < 4; i++){
/*printf("k5[%i] = %.15lf \n", i, k5[i]);*/
w[i] = y[i] + h*((9017.0/3168.0)*k1[i] - (355.0/33.0)*k2[i] + (46732.0/5247.0)*k3[i] + (49.0/176.0)*k4[i] - (5103.0/18656.0)*k5[i]) ;
}
fcn(tw, w, k6);
tw = t + h;
for(i = 0; i < 4; i++){
/*printf("k6[%i] = %.15lf \n", i, k6[i]);*/
w[i] = y[i] + h*((35.0/384.0)*k1[i] + (500.0/1113.0)*k3[i] + (125.0/192.0)*k4[i] - (2187.0/6784.0)*k5[i] + (11.0/84.0)*k6[i]);
}
fcn(tw, w, k7);
errabs = 0;
for(i = 0; i < 4; i++){
/* printf("k7[%i] = %.15lf \n", i, k7[i]);*/
/* dy[i] = h*((71.0/57600.0)*k1[i] - (71.0/16695.0)*k3[i] + (71.0/1920.0)*k4[i] - (17253.0/339200.0)*k5[i] + (22.0/525.0)*k6[i]);*/
dy[i] = h*((35.0/384.0)*k1[i] + (500.0/1113.0)*k3[i] + (125.0/192.0)*k4[i] - (2187.0/6784.0)*k5[i] + (11.0/84.0)*k6[i]);
/*err[i] = h*((71.0/57600.0)*k1[i] + (71.0/16695.0)*k3[i] + (71.0/1920.0)*k4[i] - (17253.0/339200.0)*k5[i] + (22.0/525.0)*k6[i] - (1.0/40.0)*k7[i])*/;
err[i] = h*((71.0/57600.0)*k1[i] - (71.0/16695.0)*k3[i] + (71.0/1920.0)*k4[i] - (17253.0/339200.0)*k5[i] + (22.0/525.0)*k6[i] - (1.0/40.0)*k7[i]);
/*printf("err[%i] = %.15lf \n", i, err[i]);*/
errabs+=err[i]*err[i];
}
errabs = sqrt(errabs);
printf("errabs = %.15lf\n", errabs);
if( errabs < eps){
t+= h;
printf(" FROM IF \t t = %.25lf, \n h = %.25lf, \n errabs = %.25lf, \n iteration = %i . \n", t, h, errabs, iteration);
for(i = 0; i < 4; i++){
y[i]+=dy[i];
}
}
/*Avtomaticheskiy vibor shaga*/
chi=errabs/eps;
chi = pow(chi, (1.0/6.0));
if(chi > 10) chi = 10;
if(chi < 0.1) chi = 0.1;
h*= 0.95/chi;
if( t + h > b ) h = b - t;
/* for(i = 0; i < 4; i++){
printf("y[%i] = %.15lf \n", i, y[i]);
}*/
iteration++;
printf("t = %.25lf \t h = %.25lf\n", t, h);
/*if(iteration > 5) break;*/
printf("end \n");
for(i = 0; i < 4; i++){
printf("y[%i] = %.15lf \n", i, y[i]);
}
if(iteration > 30000) break;
}
/* for(i = 0; i < 4; i++){
printf("y[%i] = %.15lf\n", i, y[i]);
}*/
return 0;
}
Try this:
Y0=initial_guess
while (true) {
F=ddopri(Y0);
Error=F-F_correct
if (Error small enough)
break;
J=jacobian(ddopri, Y0) // this is the matrix dF/dY0
Y0=Y0-J^(-1)*Error // here you have to solve a linear system
The Jacobian can be obtained using finite differences, i.e. bump up and down the elements of Y one at a time, compute F, take finite differences.
To be clear, element (i,j) of matrix J is dF_i/dY0_j

Resources