数值线性代数实验-共轭梯度法

一开始用c++的运算符重载程序总是莫名其妙的崩掉,然后以为是运算符重载的问题就写了个class对矩阵重新封装,结果还是崩,然后好久才发现是我把空间开的太大导致程序崩掉,无语,这样就浪费了我一个上午。。。。

课本上的例题:

$$
\begin{equation}
{\left[ \begin{array}{ccc}
10&1&2&3&4\\
1& 9& -1& 2& -3\\
2& -1& 7& 3& -5\\
3& 2& 3& 12& -1\\
4& -3& -5 &-1 &15
\end{array}
\right ]}\times {
\left[ \begin{array}{ccc}
x_1\\
x_2\\
x_3\\
x_4\\
x_5
\end{array}
\right ]}
={
\left[ \begin{array}{ccc}
12\\ -27\\ 14\\ -17\\ 12
\end{array}
\right ]}
\end{equation}
$$

输入数据

5 5
10 1 2 3 4
1 9 -1 2 -3
2 -1 7 3 -5
3 2 3 12 -1
4 -3 -5 -1 15
12 -27 14 -17 12

#include "cstdio"
#include "cstring"
#include "cstdlib"
#include "cmath"
#include "iostream"
using namespace std;

const double eps = 1e-6;
const int maxr = 10;
const int maxc = 10;

class Matrix {
private:
    double m[maxr][maxc];
    int row, col;
public:
    Matrix operator - (Matrix b) {
        Matrix c;
        c.col = this->col; c.row = this->row;
        for (int i = 0; i < this->row; i++) {
            for (int j = 0; j < this->col; j++) {
                c.m[i][j] = this->m[i][j]-b.m[i][j];
            }
        }
        return c;
    }
    Matrix operator + (Matrix b) {
        Matrix c;
        c.col = this->col; c.row = this->row;
        for (int i = 0; i < this->row; i++) {
            for (int j = 0; j < this->col; j++) {
                c.m[i][j] = this->m[i][j] + b.m[i][j];
            }
        }
        return c;
    }
    Matrix operator * (Matrix b) {
        Matrix c;
        memset(c.m, 0, sizeof(c.m));
        c.row = this->row; c.col = b.col;
        for (int i = 0; i < this->row; i++) {
            for (int k = 0; k < this->col; k++) {
                for (int j = 0; j < b.col; j++) {
                    c.m[i][j] += this->m[i][k]*b.m[k][j];
                }
            }
        }
        return c;
    }
    Matrix operator & (double a) {
        Matrix c = *this;
        for (int i = 0; i < this->row; i++) {
            for (int j = 0; j < this->col; j++) {
                c.m[i][j] = a*this->m[i][j];
            }
        }
        return c;
    }
    Matrix operator !() {
        Matrix c = *this;
        c.row = this->col, c.col = this->row;
        for (int i = 0; i < this->row; i++) {
            for (int j = 0; j < this->col; j++) {
                c.m[j][i] = this->m[i][j];
            }
        }
        return c;
    }
    int dcmp() {
        for (int i = 0; i < this->row; i++) {
            for (int j = 0; j < this->col; j++) {
                if (fabs(this->m[i][j]) > eps) return 1;
            }
        }
        return 0;
    }
    void show_Matrix() {
        for (int i = 0; i < this->row; i++) {
            printf("%.6f", this->m[i][0]);
            for (int j = 1; j < this->col; j++) {
                printf(" %.8f", this->m[i][j]);
            }
            printf("\n");
        }
    }
    void set_matrix(int n, int m) {
        this->row = n, this->col = m;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                scanf("%lf", &this->m[i][j]);
            }
        }
    }
    void init(int n, int m) {
        this->row = n, this->col = m;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                this->m[i][j] = 1.0;
            }
        }
    }
    int Col(){return this->col;}
    int Row(){return this->row;}
    double get(int i, int j) {return this->m[i-1][j-1];}
};

Matrix Conjugate_gradient(Matrix A, Matrix B) {
    Matrix x0 = B, p0, r1, p1;
    double alf, bet;
    x0.init(A.Col(), 1);
    Matrix r0 = B-(A*x0);
    int k = 0;
    r1 = r0;
    while (r1.dcmp()) {
        k++;
        if (k == 1) p1 = r0;
        else {
            bet = (!r1*r1).get(1, 1)/(!r0*r0).get(1, 1);
            p1 = r1 + (p0&bet);
        }
        alf = (!r1*r1).get(1, 1)/(!p1*A*p1).get(1, 1);
        x0 = x0 + (p1&alf);
        r0 = r1;
        r1 = r1-((A&alf)*p1);
    }
    return x0;
}

int main(int argc, char const *argv[])
{
   // freopen("in.txt", "r", stdin);
    Matrix A, B, C;
    int n, m;
    printf("输入系数矩阵的维数和矩阵A\n");
    scanf("%d %d", &n, &m);
    A.set_matrix(n, m);
    printf("输入矩阵B\n");
    B.set_matrix(n, 1);
    C = Conjugate_gradient(A, B);
    printf("利用共轭梯度法得到的解为\n");
    C.show_Matrix();
    return 0;
}

  

原文地址:https://www.cnblogs.com/cniwoq/p/9162944.html

时间: 2024-10-10 23:39:14

数值线性代数实验-共轭梯度法的相关文章

【matlab】matlab与线性代数实验基础

    matlab与线性代数实验基础 作者:xuan97916 一.行列式 1.行列式的输入 方括号内逐行键入元素,同一行元素用逗号或者空格,两行元素之间用分号隔开. 在命令的末尾使用分号会终止输出! A=[1,2,3;4,5,6;7,8,9] 2.行列式元素的表示 可以用一个下标表示(从上到下之字形)也可以用两个下标表示(行列)如 A(1,2) =A(4) 3.行列式的基本运算 ·         (1)读取整行:A(行数,:) (2)读取整列:A(:,列数) (3)读取行列式中的部分行列b

最优化方法:共轭梯度法(Conjugate Gradient)

http://blog.csdn.net/pipisorry/article/details/39891197 共轭梯度法(Conjugate Gradient) 共轭梯度法(英语:Conjugate gradient method).是求解数学特定线性方程组的数值解的方法.当中那些矩阵为对称和正定.共轭梯度法是一个迭代方法.它适用于稀疏矩阵线性方程组,由于这些系统对于像Cholesky分解这种直接方法太大了.这种方程组在数值求解偏微分方程时非经常见. 共轭梯度法也能够用于求解无约束的最优化问题

机器学习--线性代数基础

关闭 yunqishequ1的博客 目录视图 摘要视图 订阅 管理博客 写新文章 评论送书 | 7月书讯:众多畅销书升级!      CSDN日报20170727--<想提高团队技术,来试试这个套路!>      评论送书 | 机器学习.Java虚拟机.微信开发 机器学习--线性代数基础 2017-07-28 14:05 6人阅读 评论(0) 收藏 编辑 删除  分类: 机器x 目录(?)[+] 原文地址 数学是计算机技术的基础,线性代数是机器学习和深度学习的基础,了解数据知识最好的方法我觉得

漫步线性代数十七——正交基和格拉姆-施密特正交化(上)

对于一个正交基,每个向量和其他所有向量垂直,坐标轴就是互相正交的.我们还可以进一步改善:每个向量除以它的长度得到单位向量,这样的话正交基变成了标准正交基: 16.如果 qTiqj={01i≠j,给出正交性i=j,给出归一性 那么q1,-,qn就是是标准正交基,由标准正交列组成的矩阵叫做Q. 最重要的例子是标准基,对于x?y平面,最熟悉的e1=(1,0),e2=(0,1)水平和竖直方向都是垂直的,Q是2×2的单位矩阵.在n为空间里标准基e1,-,en由Q=I的列组成: e1=?????????10

机器学习教程 一-不懂这些线性代数知识 别说你是搞机器学习的

原文:http://www.shareditor.com/blogshow/?blogId=1 数学是计算机技术的基础,线性代数是机器学习和深度学习的基础,了解数据知识最好的方法我觉得是理解概念,数学不只是上学时用来考试的,也是工作中必不可少的基础知识,实际上有很多有趣的数学门类在学校里学不到,有很多拓展类的数据能让我们发散思维,但掌握最基本的数学知识是前提,本文就以线性代数的各种词条来做一下预热,不懂的记得百度一下. 请尊重原创,转载请注明来源网站www.shareditor.com以及原始链

10-8位7段数码管驱动实验——小梅哥FPGA设计思想与验证方法视频教程配套文档

芯航线--普利斯队长精心奉献 ? 实验目的: 1.实现FPGA驱动数码管动态显示: 2.使用In system sources and probes editor工具,输入需要显示在数码管上的的数据,数码管显示对应数值. 实验平台:芯航线FPGA核心板.数码管_VGA_PS2模块 实验原理: ????电子设计系统中常用的显示设备有数码管.LCD液晶以及VGA显示器等.其中数码管又可分为段式显示(7段.米字型等)以及点阵显示(8*8.16*16等),LCD液晶的应用可以分为字符式液晶(1602.1

20165235 实验一 Java开发环境的熟悉

20165235 实验一 Java开发环境的熟悉 一,实验内容及步骤 实验一Java开发环境的熟悉-1 建立20165235exp1文件夹,进入文件夹后建立src, bin文件夹. 使用vim编写代码. 编译代码,运行代码. 实验一Java开发环境的熟悉-2 打开IEDA并且创建项目,项目名为HelloJDB.然后在方法设置断点,run之后停在断点处. 在循环结构里设置断点,按F9停在断点处. 设置条件断点,i==50,F9,运行. 设置remove once hit一次性跑完循环体. 完成后打

Mathematica

Mathematica是一款科学计算软件,很好地结合了数值和符号计算引擎.图形系统.编程语言.文本系统.和与其他应用程序的高级连接.很多功能在相应领域内处于世界领先地位,它也是使用最广泛的数学软件之一.Mathematica的发布标志着现代科技计算的开始.Mathematica是世界上通用计算系统中最强大的系统.自从1988发布以来,它已经对如何在科技和其它领域运用计算机产生了深刻的影响. Mathematica和MATLAB.Maple并称为三大数学软件. 软件名称 Mathematica 开

【分享】近4000份数学学习资源免费分享给大家

一直以来喜欢收集数学类的教程资源,于是费了好大劲从万千合集站上扒拉了下来,总结归类了一下,一共有将近4000本电子书.经测试,均可免费下载,可能会弹出小广告,可不必理会之.[仅供学术学习和交流,请无用于商业用途.]另外,如有可能,还请尽量支持正版纸质书.   数学史(54)     数学史.rar 55.6 MB   数学的起源与发展.rar 4.3 MB   费马大定理—一个困惑了世间智者358年的谜.pdf 9.5 MB   通俗数学名著译丛14-无穷之旅:关于无穷大的文化史.pdf 14.