xref: /haiku/headers/libs/agg/agg_simul_eq.h (revision 39241fe22890fb958b6ba32d6ab9526da98be187)
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