xref: /haiku/headers/libs/agg/agg_simul_eq.h (revision e39da397f5ff79f2db9f9a3ddf1852b6710578af)
139241fe2SDarkWyrm //----------------------------------------------------------------------------
2*e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4
3*e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
439241fe2SDarkWyrm //
539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software
639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies.
739241fe2SDarkWyrm // This software is provided "as is" without express or implied
839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose.
939241fe2SDarkWyrm //
1039241fe2SDarkWyrm //----------------------------------------------------------------------------
1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com
1239241fe2SDarkWyrm //          mcseemagg@yahoo.com
1339241fe2SDarkWyrm //          http://www.antigrain.com
1439241fe2SDarkWyrm //----------------------------------------------------------------------------
1539241fe2SDarkWyrm //
1639241fe2SDarkWyrm // Solving simultaneous equations
1739241fe2SDarkWyrm //
1839241fe2SDarkWyrm //----------------------------------------------------------------------------
1939241fe2SDarkWyrm #ifndef AGG_SIMUL_EQ_INCLUDED
2039241fe2SDarkWyrm #define AGG_SIMUL_EQ_INCLUDED
2139241fe2SDarkWyrm 
2239241fe2SDarkWyrm #include <math.h>
2339241fe2SDarkWyrm #include "agg_basics.h"
2439241fe2SDarkWyrm 
2539241fe2SDarkWyrm namespace agg
2639241fe2SDarkWyrm {
2739241fe2SDarkWyrm 
2839241fe2SDarkWyrm     //=============================================================swap_arrays
swap_arrays(T * a1,T * a2,unsigned n)2939241fe2SDarkWyrm     template<class T> void swap_arrays(T* a1, T* a2, unsigned n)
3039241fe2SDarkWyrm     {
3139241fe2SDarkWyrm         unsigned i;
3239241fe2SDarkWyrm         for(i = 0; i < n; i++)
3339241fe2SDarkWyrm         {
3439241fe2SDarkWyrm             T tmp = *a1;
3539241fe2SDarkWyrm             *a1++ = *a2;
3639241fe2SDarkWyrm             *a2++ = tmp;
3739241fe2SDarkWyrm         }
3839241fe2SDarkWyrm     }
3939241fe2SDarkWyrm 
4039241fe2SDarkWyrm 
4139241fe2SDarkWyrm     //============================================================matrix_pivot
4239241fe2SDarkWyrm     template<unsigned Rows, unsigned Cols>
4339241fe2SDarkWyrm     struct matrix_pivot
4439241fe2SDarkWyrm     {
pivotmatrix_pivot4539241fe2SDarkWyrm         static int pivot(double m[Rows][Cols], unsigned row)
4639241fe2SDarkWyrm         {
4739241fe2SDarkWyrm             int k = int(row);
4839241fe2SDarkWyrm             double max_val, tmp;
4939241fe2SDarkWyrm 
5039241fe2SDarkWyrm             max_val = -1.0;
5139241fe2SDarkWyrm             unsigned i;
5239241fe2SDarkWyrm             for(i = row; i < Rows; i++)
5339241fe2SDarkWyrm             {
5439241fe2SDarkWyrm                 if((tmp = fabs(m[i][row])) > max_val && tmp != 0.0)
5539241fe2SDarkWyrm                 {
5639241fe2SDarkWyrm                     max_val = tmp;
5739241fe2SDarkWyrm                     k = i;
5839241fe2SDarkWyrm                 }
5939241fe2SDarkWyrm             }
6039241fe2SDarkWyrm 
6139241fe2SDarkWyrm             if(m[k][row] == 0.0)
6239241fe2SDarkWyrm             {
6339241fe2SDarkWyrm                 return -1;
6439241fe2SDarkWyrm             }
6539241fe2SDarkWyrm 
6639241fe2SDarkWyrm             if(k != int(row))
6739241fe2SDarkWyrm             {
6839241fe2SDarkWyrm                 swap_arrays(m[k], m[row], Cols);
6939241fe2SDarkWyrm                 return k;
7039241fe2SDarkWyrm             }
7139241fe2SDarkWyrm             return 0;
7239241fe2SDarkWyrm         }
7339241fe2SDarkWyrm     };
7439241fe2SDarkWyrm 
7539241fe2SDarkWyrm 
7639241fe2SDarkWyrm 
7739241fe2SDarkWyrm     //===============================================================simul_eq
7839241fe2SDarkWyrm     template<unsigned Size, unsigned RightCols>
7939241fe2SDarkWyrm     struct simul_eq
8039241fe2SDarkWyrm     {
solvesimul_eq8139241fe2SDarkWyrm         static bool solve(const double left[Size][Size],
8239241fe2SDarkWyrm                           const double right[Size][RightCols],
8339241fe2SDarkWyrm                           double result[Size][RightCols])
8439241fe2SDarkWyrm         {
8539241fe2SDarkWyrm             unsigned i, j, k;
8639241fe2SDarkWyrm             double a1;
8739241fe2SDarkWyrm 
8839241fe2SDarkWyrm             double tmp[Size][Size + RightCols];
8939241fe2SDarkWyrm 
9039241fe2SDarkWyrm             for(i = 0; i < Size; i++)
9139241fe2SDarkWyrm             {
9239241fe2SDarkWyrm                 for(j = 0; j < Size; j++)
9339241fe2SDarkWyrm                 {
9439241fe2SDarkWyrm                     tmp[i][j] = left[i][j];
9539241fe2SDarkWyrm                 }
9639241fe2SDarkWyrm                 for(j = 0; j < RightCols; j++)
9739241fe2SDarkWyrm                 {
9839241fe2SDarkWyrm                     tmp[i][Size + j] = right[i][j];
9939241fe2SDarkWyrm                 }
10039241fe2SDarkWyrm             }
10139241fe2SDarkWyrm 
10239241fe2SDarkWyrm             for(k = 0; k < Size; k++)
10339241fe2SDarkWyrm             {
10439241fe2SDarkWyrm                 if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0)
10539241fe2SDarkWyrm                 {
10639241fe2SDarkWyrm                     return false; // Singularity....
10739241fe2SDarkWyrm                 }
10839241fe2SDarkWyrm 
10939241fe2SDarkWyrm                 a1 = tmp[k][k];
11039241fe2SDarkWyrm 
11139241fe2SDarkWyrm                 for(j = k; j < Size + RightCols; j++)
11239241fe2SDarkWyrm                 {
11339241fe2SDarkWyrm                     tmp[k][j] /= a1;
11439241fe2SDarkWyrm                 }
11539241fe2SDarkWyrm 
11639241fe2SDarkWyrm                 for(i = k + 1; i < Size; i++)
11739241fe2SDarkWyrm                 {
11839241fe2SDarkWyrm                     a1 = tmp[i][k];
11939241fe2SDarkWyrm                     for (j = k; j < Size + RightCols; j++)
12039241fe2SDarkWyrm                     {
12139241fe2SDarkWyrm                         tmp[i][j] -= a1 * tmp[k][j];
12239241fe2SDarkWyrm                     }
12339241fe2SDarkWyrm                 }
12439241fe2SDarkWyrm             }
12539241fe2SDarkWyrm 
12639241fe2SDarkWyrm 
12739241fe2SDarkWyrm             for(k = 0; k < RightCols; k++)
12839241fe2SDarkWyrm             {
12939241fe2SDarkWyrm                 int m;
13039241fe2SDarkWyrm                 for(m = int(Size - 1); m >= 0; m--)
13139241fe2SDarkWyrm                 {
13239241fe2SDarkWyrm                     result[m][k] = tmp[m][Size + k];
13339241fe2SDarkWyrm                     for(j = m + 1; j < Size; j++)
13439241fe2SDarkWyrm                     {
13539241fe2SDarkWyrm                         result[m][k] -= tmp[m][j] * result[j][k];
13639241fe2SDarkWyrm                     }
13739241fe2SDarkWyrm                 }
13839241fe2SDarkWyrm             }
13939241fe2SDarkWyrm             return true;
14039241fe2SDarkWyrm         }
14139241fe2SDarkWyrm 
14239241fe2SDarkWyrm     };
14339241fe2SDarkWyrm 
14439241fe2SDarkWyrm 
14539241fe2SDarkWyrm }
14639241fe2SDarkWyrm 
14739241fe2SDarkWyrm #endif
148