Здесь представлены два шаблона классов: 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. Наверх |