Matrix.h包括矩陣類Matrix的定義,Matrix.cpp包括該類成員函數的實現,LinearEqu.h包括線性方程類LinearEqu的定義,繼承自Matrix類,其中solve()方法爲列主元消去法的具體步驟,LU()方法爲LU分解法的具體步驟。
//矩陣
class Matrix
{
public:
Matrix(int size = 2);
virtual ~Matrix();
void setMatrix(const double* values); //矩陣賦初值
void displayMatrix() const; //輸出矩陣
int getSize() const {return size;} //矩陣大小
double &element(int i, int j) {return elements[i * size + j];}
double element(int i, int j) const {return elements[i * size + j];}
private:
int size;
double* elements;
};
#include "Matrix.h"
#include<iostream>
using namespace std;
Matrix::Matrix(int size) : size(size){
elements = new double[size * size];
}
Matrix::~Matrix(){
delete[] elements;
}
//設置矩陣
void Matrix::setMatrix(const double* values)
{
for(int i = 0; i < size * size; i++)
elements[i] = values[i]; //矩陣元素賦值
}
//顯示矩陣
void Matrix::displayMatrix() const{
cout << "The matrix is:" << endl;
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++)
cout << element(i, j) << "\t";
cout << endl;
}
}
#include "Matrix.h"
//線性方程
class LinearEqu : public Matrix
{
public:
LinearEqu(int size = 2);
virtual ~LinearEqu();
void setLinearEqu(const double* a, const double* b); //方程賦值
bool solve(); //列主元消去法
bool LU(); //LU分解法
void displayLinearEqu() const; //顯示方程
void displaySolution() const; //顯示方程的解
private:
double* sums; //方程右端
double* solution; //方程的解s
};
// LinearEqu.cpp: implementation of the LinearEqu class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "LinearEqu.h" #include <iostream> #include <cmath> #include <vector> using namespace std; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// LinearEqu::LinearEqu(int size) : Matrix(size) { sums = new double[size]; solution = new double[size]; } LinearEqu::~LinearEqu() { delete[] sums; delete[] solution; } void LinearEqu::setLinearEqu(const double* a, const double* b){ setMatrix(a); for(int i = 0; i < this->getSize(); i++) sums[i] = b[i]; } void LinearEqu::displayLinearEqu() const{ cout << "The Linear equation is:" << endl; for(int i = 0; i < this->getSize(); i++){ for(int j = 0; j < this->getSize(); j++) cout << element(i, j) << "\t"; cout << sums[i] << endl; } } void LinearEqu::displaySolution() const{ cout << "The Result is:" << endl; for(int i = 0; i < this->getSize(); i++) cout << "x[" << i << "] = " << solution[i] << endl; } //交換 inline void swap(double &v1, double &v2){ double temp = v1; v1 = v2; v2 = temp; } //列主元消去法 bool LinearEqu::solve(){ int n = this->getSize(); for(int k = 0; k < n - 1; k++){ int is; double max = 0; for(int i = k, j = k; i < n; i++){ double t = fabs(element(i, j)); if(t > max){ max = t; is = i; } } if(max == 0){ return false; } //交換行 else{ if(is != k){ for(int j = k; j < n; j++) swap(element(k, j), element(is, j)); swap(sums[k], sums[is]); } } //消去 double major = element(k, k); for(i = k + 1; i < n; i++){ double m = element(i, k) / major; for(int j = k; j < n; j++){ element(i, j) -= element(k, j) * m; } sums[i] -= sums[k] * m; } } //判斷剩下的一個元素是否爲0 double d = element(n - 1, n - 1); if(fabs(d) < 1e-15){ return false; } //回代過程 solution[n - 1] = sums[n - 1] / d; for(int i = n - 2; i >= 0; i--){ double t = 0.0; for(int j = i + 1; j <= n - 1; j++) t += element(i, j) * solution[j]; solution[i] = (sums[i] - t)/element(i, i); } return true; } //LU分解法 bool LinearEqu::LU(){ int n = this->getSize(); vector<vector <double> > L(n ,vector<double>(n)); vector<vector <double> > U(n ,vector<double>(n)); //U第一行賦值 for(int i = 0; i < n; i++) U[0][i] = element(0, i); //L第一列賦值 for(int j = 1; j < n; j++) L[j][0] = element(j, 0) / U[0][0]; //剩餘賦值 for(i = 1; i < n; i++){ for(j = i; j < n; j++){ double sum1 = 0; for(int k = 0; k < i; k++) sum1 += L[i][k] * U[k][j]; U[i][j] = element(i, j) - sum1; } for(j = i+1; j < n; j++){ double sum2 = 0; for(int k = 0; k < i; k++) sum2 += L[j][k] * U[k][i]; L[j][i] = (element(j, i) - sum2) / U[i][i]; } } vector<double> Y(n); Y[0] = sums[0]; for (i = 1; i<n; i++) { double sum3 = 0; for (int k = 0; k<i; k++) sum3 += L[i][k] * Y[k]; Y[i] = sums[i] - sum3; } solution[n - 1] = Y[n - 1] / U[n - 1][n - 1]; for (i = n - 2; i >= 0; i--) { double sum4 = 0; for (int k = i + 1; k<n; k++) sum4 += U[i][k] * solution[k]; solution[i] = (Y[i] - sum4) / U[i][i]; } return true; } //雅可比迭代法 bool LinearEqu::Jacobi() { int n = this->getSize(); int i,j; vector<double> x1(n); vector<double> x2(n); vector<double> b(n); vector<vector <double> > a(n ,vector<double>(n)); double sum, max=INT_MAX, eps=1e-5, count=0; for(i = 0; i < n; i++){ b[i] = sums[i] / element(i, i); for(j = 0; j < n; j++){ a[i][j] = - element(i, j) / element(i, i); } a[i][i] = 0; } while(max > eps){ for(i = 0; i < n; i++){ sum = 0; for(j = 0; j < n; j++) sum += a[i][j] * x1[j]; x2[i] = sum + b[i]; solution[i] = x2[i]; } max = fabs(x1[0] - x2[0]); for(i = 1; i < n; i++) if(max < fabs(x1[i] - x2[i])) max = fabs(x1[i] - x2[i]); for(i = 0; i < n; i++){ x1[i] = x2[i]; } count++; } cout << "經過" << count << "次迭代" << endl; return true; } //高斯塞德爾迭代法 bool LinearEqu::GS() { int n = this->getSize(); int i,j,k; vector<double> x1(n); vector<double> x2(n); vector<double> b(n); vector<vector <double> > a(n ,vector<double>(n)); double sum, max=INT_MAX, eps=1e-5, count=0; for(i = 0; i < n; i++){ b[i] = sums[i] / element(i, i); for(j = 0; j < n; j++){ a[i][j] = - element(i, j) / element(i, i); } a[i][i] = 0; } while(max > eps){ for(i = 0; i < n; i++){ sum = 0; for(j = 0; j < i; j++){ sum += a[i][j] * x2[j]; } for(k = j; k < n; k++){ sum += a[i][k] * x1[k]; } x2[i] = sum + b[i]; solution[i] = x2[i]; } max = fabs(x1[0] - x2[0]); for(i = 1; i < n; i++) if(max < fabs(x1[i] - x2[i])) max = fabs(x1[i] - x2[i]); for(i = 0; i < n; i++){ x1[i] = x2[i]; } count++; } cout << "經過" << count << "次迭代" << endl; return true; }
// 列主元消去.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "LinearEqu.h" #include<iostream> using namespace std; int main(int argc, char* argv[]) { double a[] = { 12, -3, 3, -18, 3, -1, 1, 1, 1}; double b[] = {15, -15, 6}; //方程右端 LinearEqu equ(3); equ.setLinearEqu(a,b); equ.displayLinearEqu(); cout << endl; //列主元消去法: cout << "列主元消去法:" << endl; if(equ.solve()) equ.displaySolution(); else cout << "Fail" << endl; cout << endl; //LU分解法 cout << "LU分解法:" << endl; if(equ.LU()) equ.displaySolution(); else cout << "Fail" << endl; cout << endl; double c[] = { 10, -1, -2, -1, 10, -2, -1, -1, 5}; double d[] = {72, 83, 42}; LinearEqu equ2(3); equ2.setLinearEqu(c,d); equ2.displayLinearEqu(); cout << endl; //雅可比迭代法 cout << "雅可比迭代法:" << endl; if(equ2.Jacobi()) equ2.displaySolution(); else cout << "Fail" << endl; cout << endl; //高斯塞德爾迭代法 cout << "高斯塞德爾迭代法:" << endl; if(equ2.GS()) equ2.displaySolution(); else cout << "Fail" << endl; return 0; }