Здесь представлены два шаблона классов: SLU2 и SLU3, предназначенные для решения систем линейных уравнений второго и третьего порядка:
inline float qmod ( const float & x ) { return x * x; }
inline double qmod ( const double & x ) { return x * x; }
//************************ 20.11.2002 *************************//
//
// Решение систем линейных уравнений 2-го порядка методом Гаусса
// Выбор ведущего элемента по столбцам
//
//************************ 10.04.2015 *************************//
template <class T1, class T2 = T1> class SLU2
{
public:
T1 aa, ab, // aa * x + ab * y = ac
ba, bb; // ba * x + bb * y = bc
T2 ac, bc;
// Решение системы линейных уравнений 2-го порядка методом Гаусса
bool gauss ( T2 & x, T2 & y ) const
{
T2 v1, v2;
const double ma = qmod ( aa );
const double mb = qmod ( ba );
if ( ma >= mb )
{
if ( ! ma ) return false;
const T1 c = ab / aa;
const T1 b = bb - c * ba;
if ( ! b ) return false;
( v1 = ac ) /= aa;
( v2 = v1 ) *= ba;
( ( y = bc ) -= v2 ) /= b;
( v2 = y ) *= c;
}
else
{
const T1 c = bb / ba;
const T1 a = ab - c * aa;
if ( a == 0 ) return false;
( v1 = bc ) /= ba;
( v2 = v1 ) *= aa;
( ( y = ac ) -= v2 ) /= a;
( v2 = y ) *= c;
}
( x = v1 ) -= v2;
return true;
}
SLU2 & fill ( const T1 & v1, const T2 & v2 )
{
aa = ab =
ba = bb = v1;
ac = bc = v2;
return *this;
}
};
//************************ 20.11.2002 *************************//
//
// Решение систем линейных уравнений 3-го порядка методом Гаусса
// Выбор ведущего элемента по столбцам
//
//************************ 08.11.2014 *************************//
template <class T1, class T2 = T1> class SLU3
{
public:
T1 aa, ab, ac, // aa * x + ab * y + ac * z = ad
ba, bb, bc, // ba * x + bb * y + bc * z = bd
ca, cb, cc; // ca * x + cb * y + cc * z = cd
T2 ad, bd, cd;
// Решение системы линейных уравнений 3-го порядка методом Гаусса
bool gauss ( T2 & x, T2 & y, T2 & z ) const
{
SLU2<T1, T2> slu;
T1 a, b;
T2 d, e;
const double ma = qmod ( ac );
const double mb = qmod ( bc );
const double mc = qmod ( cc );
if ( mc >= mb && mc >= ma )
{
if ( ! mc ) return false;
a = ca / cc;
b = cb / cc;
( d = cd ) /= cc;
slu.aa = aa - a * ac; slu.ab = ab - b * ac; ( e = d ) *= ac; ( slu.ac = ad ) -= e;
slu.ba = ba - a * bc; slu.bb = bb - b * bc; ( e = d ) *= bc; ( slu.bc = bd ) -= e;
}
else
if ( mb >= ma )
{
a = ba / bc;
b = bb / bc;
( d = bd ) /= bc;
slu.aa = aa - a * ac; slu.ab = ab - b * ac; ( e = d ) *= ac; ( slu.ac = ad ) -= e;
slu.ba = ca - a * cc; slu.bb = cb - b * cc; ( e = d ) *= cc; ( slu.bc = cd ) -= e;
}
else
{
a = aa / ac;
b = ab / ac;
( d = ad ) /= ac;
slu.aa = ba - a * bc; slu.ab = bb - b * bc; ( e = d ) *= bc; ( slu.ac = bd ) -= e;
slu.ba = ca - a * cc; slu.bb = cb - b * cc; ( e = d ) *= cc; ( slu.bc = cd ) -= e;
}
if ( ! slu.gauss ( x, y ) ) return false;
z = d;
( e = x ) *= a; z -= e;
( e = y ) *= b; z -= e;
return true;
}
SLU3 & fill ( const T1 & v1, const T2 & v2 )
{
aa = ab = ac =
ba = bb = bc =
ca = cb = cc = v1;
ad = bd = cd = v2;
return *this;
}
};
В качестве типа Т1 можно задавать действительные ( float, double ) или комплексные числа ( Complex ).
В качестве типа Т2, кроме одиночных чисел, можно задавать наборы чисел, такие как: Vector2d,
Vector3d, Vector4d, FixArray и т. д.
Исходники находятся в файле LinAlg.h. Наверх |