1*39241fe2SDarkWyrm //---------------------------------------------------------------------------- 2*39241fe2SDarkWyrm // Anti-Grain Geometry - Version 2.2 3*39241fe2SDarkWyrm // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com) 4*39241fe2SDarkWyrm // 5*39241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software 6*39241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies. 7*39241fe2SDarkWyrm // This software is provided "as is" without express or implied 8*39241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose. 9*39241fe2SDarkWyrm // 10*39241fe2SDarkWyrm //---------------------------------------------------------------------------- 11*39241fe2SDarkWyrm // Contact: mcseem@antigrain.com 12*39241fe2SDarkWyrm // mcseemagg@yahoo.com 13*39241fe2SDarkWyrm // http://www.antigrain.com 14*39241fe2SDarkWyrm //---------------------------------------------------------------------------- 15*39241fe2SDarkWyrm // 16*39241fe2SDarkWyrm // Solving simultaneous equations 17*39241fe2SDarkWyrm // 18*39241fe2SDarkWyrm //---------------------------------------------------------------------------- 19*39241fe2SDarkWyrm #ifndef AGG_SIMUL_EQ_INCLUDED 20*39241fe2SDarkWyrm #define AGG_SIMUL_EQ_INCLUDED 21*39241fe2SDarkWyrm 22*39241fe2SDarkWyrm #include <math.h> 23*39241fe2SDarkWyrm #include "agg_basics.h" 24*39241fe2SDarkWyrm 25*39241fe2SDarkWyrm namespace agg 26*39241fe2SDarkWyrm { 27*39241fe2SDarkWyrm 28*39241fe2SDarkWyrm //=============================================================swap_arrays 29*39241fe2SDarkWyrm template<class T> void swap_arrays(T* a1, T* a2, unsigned n) 30*39241fe2SDarkWyrm { 31*39241fe2SDarkWyrm unsigned i; 32*39241fe2SDarkWyrm for(i = 0; i < n; i++) 33*39241fe2SDarkWyrm { 34*39241fe2SDarkWyrm T tmp = *a1; 35*39241fe2SDarkWyrm *a1++ = *a2; 36*39241fe2SDarkWyrm *a2++ = tmp; 37*39241fe2SDarkWyrm } 38*39241fe2SDarkWyrm } 39*39241fe2SDarkWyrm 40*39241fe2SDarkWyrm 41*39241fe2SDarkWyrm //============================================================matrix_pivot 42*39241fe2SDarkWyrm template<unsigned Rows, unsigned Cols> 43*39241fe2SDarkWyrm struct matrix_pivot 44*39241fe2SDarkWyrm { 45*39241fe2SDarkWyrm static int pivot(double m[Rows][Cols], unsigned row) 46*39241fe2SDarkWyrm { 47*39241fe2SDarkWyrm int k = int(row); 48*39241fe2SDarkWyrm double max_val, tmp; 49*39241fe2SDarkWyrm 50*39241fe2SDarkWyrm max_val = -1.0; 51*39241fe2SDarkWyrm unsigned i; 52*39241fe2SDarkWyrm for(i = row; i < Rows; i++) 53*39241fe2SDarkWyrm { 54*39241fe2SDarkWyrm if((tmp = fabs(m[i][row])) > max_val && tmp != 0.0) 55*39241fe2SDarkWyrm { 56*39241fe2SDarkWyrm max_val = tmp; 57*39241fe2SDarkWyrm k = i; 58*39241fe2SDarkWyrm } 59*39241fe2SDarkWyrm } 60*39241fe2SDarkWyrm 61*39241fe2SDarkWyrm if(m[k][row] == 0.0) 62*39241fe2SDarkWyrm { 63*39241fe2SDarkWyrm return -1; 64*39241fe2SDarkWyrm } 65*39241fe2SDarkWyrm 66*39241fe2SDarkWyrm if(k != int(row)) 67*39241fe2SDarkWyrm { 68*39241fe2SDarkWyrm swap_arrays(m[k], m[row], Cols); 69*39241fe2SDarkWyrm return k; 70*39241fe2SDarkWyrm } 71*39241fe2SDarkWyrm return 0; 72*39241fe2SDarkWyrm } 73*39241fe2SDarkWyrm }; 74*39241fe2SDarkWyrm 75*39241fe2SDarkWyrm 76*39241fe2SDarkWyrm 77*39241fe2SDarkWyrm //===============================================================simul_eq 78*39241fe2SDarkWyrm template<unsigned Size, unsigned RightCols> 79*39241fe2SDarkWyrm struct simul_eq 80*39241fe2SDarkWyrm { 81*39241fe2SDarkWyrm static bool solve(const double left[Size][Size], 82*39241fe2SDarkWyrm const double right[Size][RightCols], 83*39241fe2SDarkWyrm double result[Size][RightCols]) 84*39241fe2SDarkWyrm { 85*39241fe2SDarkWyrm unsigned i, j, k; 86*39241fe2SDarkWyrm double a1; 87*39241fe2SDarkWyrm 88*39241fe2SDarkWyrm double tmp[Size][Size + RightCols]; 89*39241fe2SDarkWyrm 90*39241fe2SDarkWyrm for(i = 0; i < Size; i++) 91*39241fe2SDarkWyrm { 92*39241fe2SDarkWyrm for(j = 0; j < Size; j++) 93*39241fe2SDarkWyrm { 94*39241fe2SDarkWyrm tmp[i][j] = left[i][j]; 95*39241fe2SDarkWyrm } 96*39241fe2SDarkWyrm for(j = 0; j < RightCols; j++) 97*39241fe2SDarkWyrm { 98*39241fe2SDarkWyrm tmp[i][Size + j] = right[i][j]; 99*39241fe2SDarkWyrm } 100*39241fe2SDarkWyrm } 101*39241fe2SDarkWyrm 102*39241fe2SDarkWyrm for(k = 0; k < Size; k++) 103*39241fe2SDarkWyrm { 104*39241fe2SDarkWyrm if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0) 105*39241fe2SDarkWyrm { 106*39241fe2SDarkWyrm return false; // Singularity.... 107*39241fe2SDarkWyrm } 108*39241fe2SDarkWyrm 109*39241fe2SDarkWyrm a1 = tmp[k][k]; 110*39241fe2SDarkWyrm 111*39241fe2SDarkWyrm for(j = k; j < Size + RightCols; j++) 112*39241fe2SDarkWyrm { 113*39241fe2SDarkWyrm tmp[k][j] /= a1; 114*39241fe2SDarkWyrm } 115*39241fe2SDarkWyrm 116*39241fe2SDarkWyrm for(i = k + 1; i < Size; i++) 117*39241fe2SDarkWyrm { 118*39241fe2SDarkWyrm a1 = tmp[i][k]; 119*39241fe2SDarkWyrm for (j = k; j < Size + RightCols; j++) 120*39241fe2SDarkWyrm { 121*39241fe2SDarkWyrm tmp[i][j] -= a1 * tmp[k][j]; 122*39241fe2SDarkWyrm } 123*39241fe2SDarkWyrm } 124*39241fe2SDarkWyrm } 125*39241fe2SDarkWyrm 126*39241fe2SDarkWyrm 127*39241fe2SDarkWyrm for(k = 0; k < RightCols; k++) 128*39241fe2SDarkWyrm { 129*39241fe2SDarkWyrm int m; 130*39241fe2SDarkWyrm for(m = int(Size - 1); m >= 0; m--) 131*39241fe2SDarkWyrm { 132*39241fe2SDarkWyrm result[m][k] = tmp[m][Size + k]; 133*39241fe2SDarkWyrm for(j = m + 1; j < Size; j++) 134*39241fe2SDarkWyrm { 135*39241fe2SDarkWyrm result[m][k] -= tmp[m][j] * result[j][k]; 136*39241fe2SDarkWyrm } 137*39241fe2SDarkWyrm } 138*39241fe2SDarkWyrm } 139*39241fe2SDarkWyrm return true; 140*39241fe2SDarkWyrm } 141*39241fe2SDarkWyrm 142*39241fe2SDarkWyrm }; 143*39241fe2SDarkWyrm 144*39241fe2SDarkWyrm 145*39241fe2SDarkWyrm } 146*39241fe2SDarkWyrm 147*39241fe2SDarkWyrm #endif 148