Advertisement
Guest User

Least Square Approx of a Quadratic Function - deturbanator

a guest
Jun 27th, 2012
3,839
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.63 KB | None | 0 0
  1. //Yay linear Algebra! This is my attempt at solving a quadratic function using 5 data points.
  2. //General theory: With points [x1,y1]...[x5,y5], and trying to fit to y = ax^2 + bx + c
  3. //In matrix form this becomes: a = [a,b,c]^T, y = [y1,...,y5]^T, and X = [(x1^2, x1, 1),...,(x5^2, x5, 1)]
  4. //In General... => (X)a = y => (X^T * X)a = (X^T)y => a = ((X^T * X)^(-1) * (X^T))y
  5. //(X^T * X) = [(sum(xi^4), sum(xi^3), sum(xi^2)), (sum(xi^3), sum(xi^2), sum(xi)), (sum(xi^2), sum(xi), sum(i))]
  6. //det((X^T *X)) = sum(xi^4)(sum(xi^2)sum(i)-sum(xi)^2) + sum(xi^3)(sum(xi)sum(xi^2)-sum(i)sum(xi^3)) + sum(xi^2)(sum(xi^3)sum(xi)-sum(xi^2)^2)
  7. // => (X^T *X)^-1 = 1/det((X^T *X)) * [{sum(i)sum(xi^2) - sum(xi)^2, -(sum(i)sum(xi^3) - sum(xi)sum(xi^2)), sum(xi)sum(xi^3)-sum(xi^2)^2}, {-(sum(i)sum(xi^3)-sum(xi^2)sum(xi), sum(i)sum(xi^4)-sum(xi^2)^2, -(sum(xi)sum(xi^4)-sum(xi^3)sum(xi^2))}, {sum(xi)sum(xi^3) - sum(xi^2)sum(xi^2), -(sum(xi)sum(xi^4) - sum(xi^2)sum(xi^3)), sum(xi^2)sum(xi^4) - sum(xi^3)sum(xi^3)}]
  8. // => (X^T *X)^-1 *X^T = stuff...
  9. //Using this info, we can now solve for coefficents!
  10.  
  11. #include <iostream>
  12. using namespace std;
  13.  
  14. int main()
  15. {
  16.     //determine how many points used
  17.     int size = 5;
  18.    
  19.     //Allocate memory for data[size][2]
  20.     //data[3][0] -> x4, data[3][1] -> y4
  21.     double **data;
  22.     data = new double*[size];
  23.     for(int i=0; i < size; i++)
  24.         data[i] = new double[2];
  25.  
  26.     // sumx3 = (x0)^3 + (x1)^3 + ... + (x{size})^3
  27.     double sumx4 = 0, sumx3 = 0, sumx2 = 0, sumx1 = 0, det;
  28.    
  29.     // Allocate memory for X^T
  30.     double **transpose;
  31.     transpose = new double*[3];
  32.     for(int i=0; i < 3; i++)
  33.         transpose[i] = new double[size];
  34.  
  35.     //Allocate memory for (X^T *X)^-1 * X^T
  36.     double **stuff;
  37.     stuff = new double*[3];
  38.     for(int i=0; i < 3; i++)
  39.         stuff[i] = new double[size];
  40.  
  41.     // y = a[0]x^2 + a[1]x + a[2]
  42.     double a[3] = {0};
  43.  
  44.     //input data, do some precalculations at the same time to avoid making more loops
  45.     for (int i=0; i < size; i++)
  46.     {
  47.         for (int j=0; j < 2; j++)
  48.         {
  49.             cin >> data[i][j];
  50.             //these computations only happen with x values
  51.             if(j==0)
  52.             {
  53.                 //develops the sum values needed for inverse
  54.                 sumx4 += data[i][j]*data[i][j]*data[i][j]*data[i][j];
  55.                 sumx3 += data[i][j]*data[i][j]*data[i][j];
  56.                 sumx2 += data[i][j]*data[i][j];
  57.                 sumx1 += data[i][j];
  58.                
  59.                 //develops transpose matrix
  60.                 transpose[2][i] = 1;
  61.                 transpose[1][i] = data[i][j];
  62.                 transpose[0][i] = data[i][j]*data[i][j];
  63.             }
  64.         }
  65.     }
  66.    
  67. //After solving all the math
  68.     //determinate
  69.     det = (sumx4*sumx2*size) + (sumx3*sumx1*sumx2) + (sumx2*sumx3*sumx1) - (sumx2*sumx2*sumx2) - (sumx1*sumx1*sumx4) - (size*sumx3*sumx3);
  70.  
  71.     //precalculated the inverse matrix to avoid numerical methods which take time or lose accuracy, NOTE: does not include division of determinate
  72.     double inverse[3][3] = {
  73.         {size*sumx2 - sumx1*sumx1, -(size*sumx3 - sumx1*sumx2), sumx1*sumx3-sumx2*sumx2},
  74.         {-(size*sumx3-sumx2*sumx1), size*sumx4-sumx2*sumx2, -(sumx1*sumx4-sumx3*sumx2)},
  75.         {sumx1*sumx3 - sumx2*sumx2, -(sumx1*sumx4 - sumx2*sumx3), sumx2*sumx4 - sumx3*sumx3}
  76.     };
  77.  
  78.     //This is matrix multiplication for this particular pair of matrices
  79.     for (int i=0; i < 3; i++)
  80.     {
  81.         for (int j=0; j < size; j++)
  82.         {
  83.             stuff[i][j] = inverse[i][0]*transpose[0][j] + inverse[i][1]*transpose[1][j] + inverse[i][2]*transpose[2][j];
  84.         }
  85.     }
  86.  
  87.     //This is the final matrix multiplication that outputs a 1x3 matrix with our curve parameters
  88.     for (int i=0; i < 3; i++)
  89.     {
  90.         for (int j=0; j < size; j++)
  91.         {
  92.             a[i] += stuff[i][j]*data[j][1];
  93.         }
  94.         //dont forget to divide by determinate
  95.         a[i] /= det;
  96.     }
  97.  
  98.     cout << endl << "a: " << a[0] << " b: " << a[1] << " c: " << a[2] << endl;
  99. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement