Blender V2.61 - r43446

LU_HELPER.cpp

Go to the documentation of this file.
00001 
00005 #include "LU_HELPER.h"
00006 
00007 int isNonsingular (sLU LU_) {
00008       for (int j = 0; j < 3; j++) {
00009          if (LU_.values[j][j] == 0)
00010             return 0;
00011       }
00012       return 1;
00013 }
00014 
00015 sLU computeLU( float a[3][3])
00016 {
00017     sLU result;
00018     int m=3;
00019     int n=3;
00020 
00021     //float LU_[3][3];
00022     for (int i = 0; i < m; i++) {
00023             result.piv[i] = i;
00024             for (int j = 0; j < n; j++) result.values[i][j]=a[i][j];
00025       }
00026 
00027       result.pivsign = 1;
00028       //Real *LUrowi = 0;;
00029       //Array1D<Real> LUcolj(m);
00030       //float *LUrowi = 0;
00031       float LUcolj[3];
00032 
00033       // Outer loop.
00034 
00035       for (int j = 0; j < n; j++) {
00036 
00037          // Make a copy of the j-th column to localize references.
00038 
00039          for (int i = 0; i < m; i++) {
00040             LUcolj[i] = result.values[i][j];
00041          }
00042 
00043          // Apply previous transformations.
00044 
00045          for (int i = 0; i < m; i++) {
00046              //float LUrowi[3];
00047              //LUrowi = result.values[i];
00048 
00049             // Most of the time is spent in the following dot product.
00050 
00051             int kmax = min(i,j);
00052             double s = 0.0;
00053             for (int k = 0; k < kmax; k++) {
00054                s += result.values[i][k]*LUcolj[k];
00055             }
00056 
00057             result.values[i][j] = LUcolj[i] -= s;
00058          }
00059    
00060          // Find pivot and exchange if necessary.
00061 
00062          int p = j;
00063          for (int i = j+1; i < m; i++) {
00064             if (abs(LUcolj[i]) > abs(LUcolj[p])) {
00065                p = i;
00066             }
00067          }
00068          if (p != j) {
00069             int k=0;
00070             for (k = 0; k < n; k++) {
00071                double t = result.values[p][k]; 
00072                result.values[p][k] = result.values[j][k]; 
00073                result.values[j][k] = t;
00074             }
00075             k = result.piv[p]; 
00076             result.piv[p] = result.piv[j]; 
00077             result.piv[j] = k;
00078             result.pivsign = -result.pivsign;
00079          }
00080 
00081          // Compute multipliers.
00082          
00083          if ((j < m) && (result.values[j][j] != 0.0)) {
00084             for (int i = j+1; i < m; i++) {
00085                result.values[i][j] /= result.values[j][j];
00086             }
00087          }
00088       }
00089 
00090       return result;
00091 }
00092 
00093 void solveLU3x3(sLU& A, float x[3], float b[3])
00094 {
00095   //TNT::Array1D<float> jamaB = TNT::Array1D<float>(3, &b[0]);
00096   //TNT::Array1D<float> jamaX = A.solve(jamaB);
00097 
00098     
00099   // Solve A, B
00100 
00101     {
00102       if (!isNonsingular(A)) {
00103         x[0]=0.0f;
00104         x[1]=0.0f;
00105         x[2]=0.0f;
00106         return;
00107       }
00108 
00109 
00110       //Array1D<Real> Ax = permute_copy(b, piv);
00111       float Ax[3];
00112 
00113     // permute copy: b , A.piv
00114     {
00115          for (int i = 0; i < 3; i++) 
00116                Ax[i] = b[A.piv[i]];
00117     }
00118 
00119       // Solve L*Y = B(piv)
00120       for (int k = 0; k < 3; k++) {
00121          for (int i = k+1; i < 3; i++) {
00122                Ax[i] -= Ax[k]*A.values[i][k];
00123             }
00124          }
00125       
00126       // Solve U*X = Y;
00127       for (int k = 2; k >= 0; k--) {
00128             Ax[k] /= A.values[k][k];
00129             for (int i = 0; i < k; i++) 
00130                 Ax[i] -= Ax[k]*A.values[i][k];
00131       }
00132      
00133 
00134         x[0] = Ax[0];
00135         x[1] = Ax[1];
00136         x[2] = Ax[2];
00137       return;
00138     }
00139 }