热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【数值计算】花式解线性方程组

Assignment1LU分解codes参考文献Assignment2迭代法

  • Assignment1 LU分解
    • codes
    • 参考文献
  • Assignment2 迭代法
    • Problem
    • 数据生成
    • norm
    • slow_Jacobi
    • 清真_Jacobi
    • Gauss-Seidel
    • SOR超松弛法
    • 参考文献
  • Assignment3CGQR
    • Problem
    • Conjugate Gradient Method 共轭梯度法
    • QR Method
    • 参考文献

Assignment1: LU分解

老师让只交.py,

于是很多东西直接在注释里写了

codes

# -*-encoding:utf-8-*-
# Numerical Computation & Optimization
# homework1: LU decomposition
# cww97
# 2017/09/27
# from cww97jh@gmail.com
# to num_com_opt@163.com
from numpy import *
n = 100


def lu(A):  #
    """ Doolittle decomposition(course book page45) I just copy the formula from the course book :param A: the Coefficient matrix :return: L, U the lower & upper matrix """
    L = mat(eye(n))  # low matrix
    U = mat(zeros((n, n)))   # upper matrix
    for k in range(n):  # k-th step
        for i in range(k, n):  # calc k-th row of U
            U[k, i] = A[k, i] - sum(L[k, j]*U[j, i] for j in range(k))
        for i in range(k+1, n):  # k-th col of L
            L[i, k] = (A[i, k] - sum(L[i, j]*U[j, k] for j in range(k))) / U[k, k]
    return L, U


def calc(A, B):
    """ calc the equation Ax = b(course book page46) I just copy the formula from the course book :param L: lower triangle matrix :param U: upper triangle matrix :param B: B = A * X :return: the x of A * X = B """
    L, U = lu(A)
    # first, calc L * Y = B, get Y
    Y = mat(zeros((n, 1)))
    for k in range(n):
        Y[k, 0] = B[k, 0] - sum(L[k, j]*Y[j, 0] for j in range(k))
    # then, calc U * X = Y, get X
    X = mat(zeros((n, 1)))
    for k in range(n-1, -1, -1):
        X[k, 0] = (Y[k, 0] - sum(U[k, j]* X[j, 0] for j in range(k+1, n))) / U[k, k]
    return X


""" sample data on course book, for debug A = mat([[2, 1, 5], [4, 1, 12], [-2, -4, 5]]) B = mat([[11], [27], [12]]) """
if __name__ == '__main__':
    # Generate a random matrix M &
    M = mat(random.randint(1, 100, size=(n, n)))
    # A = M + I(Identity matrix)
    A = M + mat(eye(n))
    print('---------matrix A:----------\n', A,)
    # Generate a vector x = (1,2,··· ,100).T
    X = mat([[i+1] for i in range(n)])
    print('---------vector X:----------\n', X.T, '.T')
    # Generate the vector b as b = A * x
    B = A * X
    print('-------B = A * X:-----------\n', B.T, '.T')
    x = calc(A, B)
    print('calc the equation A * x = B, x:\n', x.T, '.T')

""" finished this, when I need to calc some equation, I think I may more likely to use this: x = np.linalg.solve(A, b) However, If I use this, this homework may cannot pass >_

参考文献

python 矩阵操作

Assignment2: 迭代法

TAGS: 数值计算

数值计算与优化 指导老师: 王祥丰

陈伟文 10152510217

Problem

这里写图片描述

数据生成

def get_data():
    # Generate a random matrix M &
    A = mat(zeros((N, N)))
    for i in range(N):
        A[i, i] = 2
    for i in range(N-1):
        A[i, i + 1] = -1
        A[i + 1, i] = -1
    print('---------matrix A:----------\n', A,)
    # Generate a vector b = (1,1,··· ,1).T
    b = mat(ones((N, 1)))
    print('---------vector X:----------\n', b.T, '.T')
    return A, b

norm

vector norm

这里写图片描述

matrix norm

这里写图片描述

slow_Jacobi

Wiki

核心算法

这里写图片描述

根据最后一个公式,写出如下代码

def norm(x):
    ans = 0
    for t in x:
        ans += square(t[0, 0])
    return sqrt(ans)


def jacobi(A, b):
    n = len(b)
    x0 = mat(zeros((n, 1)))
    x1 = mat(zeros((n, 1)))
    d = 1
    ti = 0
    while d > eps:
        for i in range(n):
            tmp = 0
            for j in range(n):
                if j != i:
                    tmp += A[i, j] * x0[j, 0]
            x1[i, 0] = 1./A[i, i] * (b[i, 0] - tmp)
            #print(x1.T)
        x0 = x1
        d = 1.*norm(A * x0 - b) / norm(b)
        ti += 1
        print('time = %d, d = %lf' % (ti, d))
    return x1

跑了好久好久好久,,,我问主席跑了多久

这里写图片描述为啥他能跑这么快摔

于是乎我瞄了一眼他的代码,发现,他没像我这样一个值一个值的计算,而是使用numpy自带的矩阵运算
好的,我傻了,又自造车轮,太好了这里写图片描述

于是我决定把上面的函数命名为slow_jacobi,来纪念我这个zz的操作

不过好歹等了十几分钟还是有结果出来的

这里写图片描述

运行速度慢了,不过迭代次数少了,不行,这么慢的代码我不能忍,重写

清真_Jacobi

用这个式子

Xk+1=D1(bRxk)

def jacobi(A, b):  # 这次吸取教训,多用矩阵运算
    # X^(k+1) = D^−1 (b − R * x^k)
    n = len(b)
    x0 = mat(zeros((n, 1)))
    x1 = mat(zeros((n, 1)))
    D = mat(diag(diag(A).tolist()))
    R = A - D
    norm_b = linalg.norm(b)
    d = 1; ti = 0
    while d > eps:
        x1 = D.I * (b - R * x0)
        x0 = x1; ti += 1
        d = linalg.norm(A * x0 - b) / norm_b
        print('time = %d, delta = %.8lf' % (ti, d))
    return x0

迭代次数多了,不过10秒内出解

这里写图片描述

不要自造车轮,不要自造车轮,不要自造车轮

Gauss-Seidel

又是一波紧张刺激的抄公式(偷懒直接贴ppt了)

这里写图片描述

这里写图片描述

核心迭代还是抄一下吧

xk+1=BGxk+fG

BG=(DL)1fG=(DL)1b

这个迭代可以用x迭代x

def gauss_seidel(A, b):
    # $x ^ {k + 1} = B_G x ^ k + f_G$
    # $B_G = (D - L) ^ {-1}, f_G = (D - L) ^ {-1}b$
    n = len(b)
    D = mat(diag(diag(A).tolist()))
    U = mat(zeros((n, n))) - triu(A, 1)
    L = mat(zeros((n, n))) - tril(A, -1)
    bg = (D - L).I * U
    fg = (D - L).I * b
    norm_b = linalg.norm(b)
    x = mat(zeros((n, 1)))
    d = 1; ti = 0
    while d > eps:
        x = bg * x + fg
        ti += 1
        d = linalg.norm(A * x - b) / norm_b
        print('time = %d, delta = %.8lf' % (ti, d))
    return x

迭代次数少了很多

这里写图片描述

SOR超松弛法

抄ppt

这里写图片描述

xk+1=Bwxk+fw

Bw=(DwL)1[(1w)D+wU]

fw=w(DwL)1b

关于 ω 的取值(ppt上写成了 w ),这篇论文,下载之后发现一共只有四页

这里写图片描述

一个跟实验报告一样的论文,还是c语言实现的

互动百科这么说

这里写图片描述

看来这个 ω 取值,在 1 之间取吧 2 ,就是看脸

def sor(A, b, w):
    # $x^{k+1} = B_w x^k + f_w$
    # $B_w = (D - wL)^{-1}[(1-w)D + wU]$
    # $f_w = w(D - wL)^{-1}b$
    n = len(b)
    D = mat(diag(diag(A).tolist()))
    U = mat(zeros((n, n))) - triu(A, 1)
    L = mat(zeros((n, n))) - tril(A, -1)
    bw = (D - w * L).I * ((1-w)*D + w*U)
    fw = w * (D - w*L).I * b

    norm_b = linalg.norm(b)
    x = mat(zeros((n, 1)))
    d = 1; ti = 0
    while d > eps:
        x = bw * x + fw
        ti += 1
        d = linalg.norm(A * x - b) / norm_b
    print('w = %.2lf, time = %d' % (w, ti))
    return x

这个时候我已经不关心是否能出正解了,肯定是正解

为了测试下 ω 的取值对迭代次数的影响

我又写了如下循环

    w = 1.
    while w <= 2:
        w += 0.1
        x = sor(A, b, w)

output:

w = 1.10, time = 11597
w = 1.20, time = 9448
w = 1.30, time = 7630
w = 1.40, time = 6071
w = 1.50, time = 4719
w = 1.60, time = 3536
w = 1.70, time = 2489
w = 1.80, time = 1554
w = 1.90, time = 696

是越大越快吗,我又改循环:

    w = 1.8
    while w <2:
        w += 0.01
        x = sor(A, b, w)

得到如下输出

w = 1.81, time = 1466
w = 1.82, time = 1378
w = 1.83, time = 1292
w = 1.84, time = 1205
w = 1.85, time = 1120
w = 1.86, time = 1035
w = 1.87, time = 950
w = 1.88, time = 866
w = 1.89, time = 781
w = 1.90, time = 696
w = 1.91, time = 609
w = 1.92, time = 520
w = 1.93, time = 423
w = 1.94, time = 293
w = 1.95, time = 303
w = 1.96, time = 404
w = 1.97, time = 505
w = 1.98, time = 808
w = 1.99, time = 1515

我觉得没有必要继续枚举了

我只能说对于本题, ω 1.94 的时候速度最快

参考文献

[1] Lecture-3课程ppt

[2] wiki_jacobi

[3] 数值计算——线性方程组的迭代法

[4] 胡 枫 ,于福溪 《超松弛迭代法中松弛因子 ω的选取方法》 青海师范大学学报 2006.01.13 42-46

[5] 互动百科_松弛法

[6] numpy文档_上三角矩阵

[7] numpy文档_norm

Assignment3:CG&QR

陈伟文 10152510217

2017/10/19

Problem

Calculate the equation Ax = b through Conjugate Gradient Method
and QR Method respectively

Conjugate Gradient Method 共轭梯度法

wiki,中文wiki只有寥寥几句,英文的比较详细

贴ppt

这里写图片描述

观察了一下每次循环的逻辑:

  1. 先x,用到了上一步的x和p,
  2. r,用到上一步的r和p
  3. p,用到刚刚算出的r和上一步的p

很显然可以发现,x,r,p只需要一个变量就可以完成循环

def conjugate_gradient(A, b):
    n = len(b)
    norm_b = linalg.norm(b)
    # generate x0, r0, p0
    x = mat(zeros((n, 1)))
    r = b - A * x; p = r  # 1
    # here we go
    d = 1; ti = 0
    while d > eps:  #2
        ap = A * p  # 3
        a = (float)(1.*(r.T * r) / (p.T * ap))
        x += a * p  # 4
        r -= a * ap  # 5
        p = r + (float)(1.*(r.T * ap) / (p.T * ap)) * p  #6
        # for counting
        ti += 1
        d = linalg.norm(A * x - b) / norm_b
        print('time = %d, d = %f' % (ti, d))
    return x

我已经不关心方程解出来的正确性了(肯定是对的),看迭代次数吧

这里写图片描述

QR Method

先贴公式

先算Q
这里写图片描述

然后算R

这里写图片描述

(tips:这里的R特别容易算错)

最后 : RX=QTb

def QR(A, b):
    n = len(b)
    # calc Q
    R = mat(zeros((n, n)))
    R[0, 0] = linalg.norm(A[:, 0])
    Q = A.copy()
    Q[:, 0] = A[:, 0] / linalg.norm(A[:, 0])
    for j in range(1, n):
        for i in range(j):
            Q[:, j] -= float(A[:, j].T * Q[:, i]) * Q[:, i]
        R[j, j] = linalg.norm(Q[:, j])
        Q[:, j] /= linalg.norm(Q[:, j])
    # calc R
    for i in range(n):
        for j in range(i+1, n):
            R[i, j] = float(A[:, j].T * Q[:, i])
    # calc x from Rx = Q^T * b
    b = Q.T * b
    x = mat(zeros((n, 1)))
    for i in range(n-1, -1, -1):
        x[i] = (b[i] - R[i, i+1:] * x[i+1:]) / R[i, i]
    return x

输出取了整:

calc the equation A * x = B, x:
 [[   50.    99.   147.   194.   240.   285.   329.   372.   414.   455.
    495.   534.   572.   609.   645.   680.   714.   747.   779.   810.
    840.   869.   897.   924.   950.   975.   999.  1022.  1044.  1065.
   1085.  1104.  1122.  1139.  1155.  1170.  1184.  1197.  1209.  1220.
   1230.  1239.  1247.  1254.  1260.  1265.  1269.  1272.  1274.  1275.
   1275.  1274.  1272.  1269.  1265.  1260.  1254.  1247.  1239.  1230.
   1220.  1209.  1197.  1184.  1170.  1155.  1139.  1122.  1104.  1085.
   1065.  1044.  1022.   999.   975.   950.   924.   897.   869.   840.
    810.   779.   747.   714.   680.   645.   609.   572.   534.   495.
    455.   414.   372.   329.   285.   240.   194.   147.    99.    50.]] .T

参考文献

[1] numpyt.dot 计算矩阵内积

[2] dot常见error

[3] numpy线性代数

[4] numpy行列操作


推荐阅读
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
author-avatar
娟紫恋蓝_610
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有