线性代数-Python-04:线性系统+高斯消元的实现

news2025/4/18 5:28:45

文章目录

  • 1 线性系统
  • 2 高斯-jordon消元法的实现
      • 2.1 Matrix
      • 2.2 Vector
      • 2.3 线性系统
  • 3 行最简形式
  • 4 线性方程组的结构
  • 5 线性方程组-通用高斯消元的实现
    • 5.1 global
    • 5.2 Vector-引入is_zero
    • 5.3 LinearSystem
    • 5.4 main

1 线性系统

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2 高斯-jordon消元法的实现

2.1 Matrix

from .Vector import Vector

class Matrix:

    def __init__(self, list2d):
        self._values = [row[:] for row in list2d]

    @classmethod
    def zero(cls, r, c):
        """返回一个r行c列的零矩阵"""
        return cls([[0] * c for _ in range(r)])

    @classmethod
    def identity(cls, n):
        """返回一个n行n列的单位矩阵"""
        m = [[0]*n for _ in range(n)]
        for i in range(n):
            m[i][i] = 1;
        return cls(m)

    def T(self):
        """返回矩阵的转置矩阵"""
        return Matrix([[e for e in self.col_vector(i)]
                       for i in range(self.col_num())])

    def __add__(self, another):
        """返回两个矩阵的加法结果"""
        assert self.shape() == another.shape(), \
            "Error in adding. Shape of matrix must be same."
        return Matrix([[a + b for a, b in zip(self.row_vector(i), another.row_vector(i))]
                       for i in range(self.row_num())])

    def __sub__(self, another):
        """返回两个矩阵的减法结果"""
        assert self.shape() == another.shape(), \
            "Error in subtracting. Shape of matrix must be same."
        return Matrix([[a - b for a, b in zip(self.row_vector(i), another.row_vector(i))]
                       for i in range(self.row_num())])

    def dot(self, another):
        """返回矩阵乘法的结果"""
        if isinstance(another, Vector):
            # 矩阵和向量的乘法
            assert self.col_num() == len(another), \
                "Error in Matrix-Vector Multiplication."
            return Vector([self.row_vector(i).dot(another) for i in range(self.row_num())])

        if isinstance(another, Matrix):
            # 矩阵和矩阵的乘法
            assert self.col_num() == another.row_num(), \
                "Error in Matrix-Matrix Multiplication."
            return Matrix([[self.row_vector(i).dot(another.col_vector(j)) for j in range(another.col_num())]
                           for i in range(self.row_num())])

    def __mul__(self, k):
        """返回矩阵的数量乘结果: self * k"""
        return Matrix([[e * k for e in self.row_vector(i)]
                       for i in range(self.row_num())])

    def __rmul__(self, k):
        """返回矩阵的数量乘结果: k * self"""
        return self * k

    def __truediv__(self, k):
        """返回数量除法的结果矩阵:self / k"""
        return (1 / k) * self

    def __pos__(self):
        """返回矩阵取正的结果"""
        return 1 * self

    def __neg__(self):
        """返回矩阵取负的结果"""
        return -1 * self

    def row_vector(self, index):
        """返回矩阵的第index个行向量"""
        return Vector(self._values[index])

    def col_vector(self, index):
        """返回矩阵的第index个列向量"""
        return Vector([row[index] for row in self._values])

    def __getitem__(self, pos):
        """返回矩阵pos位置的元素"""
        r, c = pos
        return self._values[r][c]

    def size(self):
        """返回矩阵的元素个数"""
        r, c = self.shape()
        return r * c

    def row_num(self):
        """返回矩阵的行数"""
        return self.shape()[0]

    __len__ = row_num

    def col_num(self):
        """返回矩阵的列数"""
        return self.shape()[1]

    def shape(self):
        """返回矩阵的形状: (行数, 列数)"""
        return len(self._values), len(self._values[0])

    def __repr__(self):
        return "Matrix({})".format(self._values)

    __str__ = __repr__

2.2 Vector

import math
from ._globals import EPSILON
class Vector:

    def __init__(self, lst):
        """
        __init__ 代表类的构造函数
        双下划线开头的变量 例如_values,代表类的私有成员
        lst是个引用,list(lst)将值复制一遍,防止用户修改值
        """
        self._values = list(lst)

    def underlying_list(self):
        """返回向量的底层列表"""
        return self._values[:]

    def dot(self, another):
        """向量点乘,返回结果标量"""
        assert len(self) == len(another), \
            "Error in dot product. Length of vectors must be same."
        return sum(a * b for a, b in zip(self, another))

    def norm(self):
        """返回向量的模"""
        return math.sqrt(sum(e**2 for e in self))

    def normalize(self):
        """
        归一化,规范化
        返回向量的单位向量
        此处设计到了除法: def __truediv__(self, k):
        """
        if self.norm() < EPSILON:
            raise ZeroDivisionError("Normalize error! norm is zero.")
        return Vector(self._values) / self.norm()
        # return 1 / self.norm() * Vector(self._values)
        # return Vector([e / self.norm() for e in self])

    def __truediv__(self, k):
        """返回数量除法的结果向量:self / k"""
        return (1 / k) * self

    @classmethod
    def zero(cls, dim):
        """返回一个dim维的零向量
        @classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的cls参数,可以来调用类的属性,类的方法,实例化对象等。
        """
        return cls([0] * dim)

    def __add__(self, another):
        """向量加法,返回结果向量"""
        assert len(self) == len(another), \
            "Error in adding. Length of vectors must be same."
        # return Vector([a + b for a, b in zip(self._values, another._values)])
        return Vector([a + b for a, b in zip(self, another)])

    def __sub__(self, another):
        """向量减法,返回结果向量"""
        assert len(self) == len(another), \
            "Error in subtracting. Length of vectors must be same."
        return Vector([a - b for a, b in zip(self, another)])

    def __mul__(self, k):
        """返回数量乘法的结果向量:self * k"""
        return Vector([k * e for e in self])

    def __rmul__(self, k):
        """
        返回数量乘法的结果向量:k * self
        self本身就是一个列表
        """
        return self * k

    def __pos__(self):
        """返回向量取正的结果向量"""
        return 1 * self

    def __neg__(self):
        """返回向量取负的结果向量"""
        return -1 * self

    def __iter__(self):
        """返回向量的迭代器"""
        return self._values.__iter__()

    def __getitem__(self, index):
        """取向量的第index个元素"""
        return self._values[index]

    def __len__(self):
        """返回向量长度(有多少个元素)"""
        return len(self._values)

    def __repr__(self):
        """打印显示:Vector([5, 2])"""
        return "Vector({})".format(self._values)

    def __str__(self):
        """打印显示:(5, 2)"""
        return "({})".format(", ".join(str(e) for e in self._values))

2.3 线性系统

from .Matrix import Matrix
from .Vector import Vector


class LinearSystem:

    def __init__(self, A, b):

        assert A.row_num() == len(b), "row number of A must be equal to the length of b"
        self._m = A.row_num()
        self._n = A.col_num()
        assert self._m == self._n  # TODO: no this restriction

        self.Ab = [Vector(A.row_vector(i).underlying_list() + [b[i]])
                   for i in range(self._m)]

    def _max_row(self, index_i, index_j, n):

        best, ret = abs(self.Ab[index_i][index_j]), index_i
        for i in range(index_i + 1, n):
            if abs(self.Ab[i][index_j]) > best:
                best, ret = abs(self.Ab[i][index_j]), i
        return ret

    def _forward(self):

        n = self._m
        for i in range(n):
            # Ab[i][i]为主元
            max_row = self._max_row(i, i, n)
            self.Ab[i], self.Ab[max_row] = self.Ab[max_row], self.Ab[i]

            # 将主元归为一
            self.Ab[i] = self.Ab[i] / self.Ab[i][i]  # TODO: self.Ab[i][i] == 0?
            for j in range(i + 1, n):
                self.Ab[j] = self.Ab[j] - self.Ab[j][i] * self.Ab[i]

    def _backward(self):

        n = self._m
        for i in range(n - 1, -1, -1):
            # Ab[i][i]为主元
            for j in range(i - 1, -1, -1):
                self.Ab[j] = self.Ab[j] - self.Ab[j][i] * self.Ab[i]

    def gauss_jordan_elimination(self):

        self._forward()
        self._backward()

    def fancy_print(self):

        for i in range(self._m):
            print(" ".join(str(self.Ab[i][j]) for j in range(self._n)), end=" ")
            print("|", self.Ab[i][-1])

3 行最简形式

在这里插入图片描述

4 线性方程组的结构

在这里插入图片描述
在这里插入图片描述

5 线性方程组-通用高斯消元的实现

5.1 global

# 包中的变量,但是对包外不可见,因此使用“_”开头
EPSILON = 1e-8


def is_zero(x):
    return abs(x) < EPSILON


def is_equal(a, b):
    return abs(a - b) < EPSILON

5.2 Vector-引入is_zero

import math
from ._globals import is_zero
class Vector:

    def __init__(self, lst):
        """
        __init__ 代表类的构造函数
        双下划线开头的变量 例如_values,代表类的私有成员
        lst是个引用,list(lst)将值复制一遍,防止用户修改值
        """
        self._values = list(lst)

    def underlying_list(self):
        """返回向量的底层列表"""
        return self._values[:]

    def dot(self, another):
        """向量点乘,返回结果标量"""
        assert len(self) == len(another), \
            "Error in dot product. Length of vectors must be same."
        return sum(a * b for a, b in zip(self, another))

    def norm(self):
        """返回向量的模"""
        return math.sqrt(sum(e**2 for e in self))

    def normalize(self):
        """
        归一化,规范化
        返回向量的单位向量
        此处设计到了除法: def __truediv__(self, k):
        """
        if is_zero(self.norm()):
            raise ZeroDivisionError("Normalize error! norm is zero.")
        return Vector(self._values) / self.norm()
        # return 1 / self.norm() * Vector(self._values)
        # return Vector([e / self.norm() for e in self])

    def __truediv__(self, k):
        """返回数量除法的结果向量:self / k"""
        return (1 / k) * self

    @classmethod
    def zero(cls, dim):
        """返回一个dim维的零向量
        @classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的cls参数,可以来调用类的属性,类的方法,实例化对象等。
        """
        return cls([0] * dim)

    def __add__(self, another):
        """向量加法,返回结果向量"""
        assert len(self) == len(another), \
            "Error in adding. Length of vectors must be same."
        # return Vector([a + b for a, b in zip(self._values, another._values)])
        return Vector([a + b for a, b in zip(self, another)])

    def __sub__(self, another):
        """向量减法,返回结果向量"""
        assert len(self) == len(another), \
            "Error in subtracting. Length of vectors must be same."
        return Vector([a - b for a, b in zip(self, another)])

    def __mul__(self, k):
        """返回数量乘法的结果向量:self * k"""
        return Vector([k * e for e in self])

    def __rmul__(self, k):
        """
        返回数量乘法的结果向量:k * self
        self本身就是一个列表
        """
        return self * k

    def __pos__(self):
        """返回向量取正的结果向量"""
        return 1 * self

    def __neg__(self):
        """返回向量取负的结果向量"""
        return -1 * self

    def __iter__(self):
        """返回向量的迭代器"""
        return self._values.__iter__()

    def __getitem__(self, index):
        """取向量的第index个元素"""
        return self._values[index]

    def __len__(self):
        """返回向量长度(有多少个元素)"""
        return len(self._values)

    def __repr__(self):
        """打印显示:Vector([5, 2])"""
        return "Vector({})".format(self._values)

    def __str__(self):
        """打印显示:(5, 2)"""
        return "({})".format(", ".join(str(e) for e in self._values))

5.3 LinearSystem

from .Matrix import Matrix
from .Vector import Vector
from ._globals import is_zero


class LinearSystem:

    def __init__(self, A, b):

        assert A.row_num() == len(b), "row number of A must be equal to the length of b"
        self._m = A.row_num()
        self._n = A.col_num()
        # assert self._m == self._n  # TODO: no this restriction

        self.Ab = [Vector(A.row_vector(i).underlying_list() + [b[i]])
                   for i in range(self._m)]
        self.pivots = []

    def _max_row(self, index_i, index_j, n):

        best, ret = abs(self.Ab[index_i][index_j]), index_i
        for i in range(index_i + 1, n):
            if abs(self.Ab[i][index_j]) > best:
                best, ret = abs(self.Ab[i][index_j]), i
        return ret

    def _forward(self):

        i, k = 0, 0
        while i < self._m and k < self._n:
            # 看Ab[i][k]位置是否可以是主元
            max_row = self._max_row(i, k, self._m)
            self.Ab[i], self.Ab[max_row] = self.Ab[max_row], self.Ab[i]

            if is_zero(self.Ab[i][k]):
                k += 1
            else:
                # 将主元归为一
                self.Ab[i] = self.Ab[i] / self.Ab[i][k]
                for j in range(i + 1, self._m):
                    self.Ab[j] = self.Ab[j] - self.Ab[j][k] * self.Ab[i]
                self.pivots.append(k)
                i += 1

    def _backward(self):

        n = len(self.pivots)
        for i in range(n - 1, -1, -1):
            k = self.pivots[i]
            # Ab[i][k]为主元
            for j in range(i - 1, -1, -1):
                self.Ab[j] = self.Ab[j] - self.Ab[j][k] * self.Ab[i]

    def gauss_jordan_elimination(self):
        """如果有解,返回True;如果没有解,返回False"""
        self._forward()
        self._backward()

        for i in range(len(self.pivots), self._m):
            if not is_zero(self.Ab[i][-1]):
                return False
        return True

    def fancy_print(self):

        for i in range(self._m):
            print(" ".join(str(self.Ab[i][j]) for j in range(self._n)), end=" ")
            print("|", self.Ab[i][-1])

5.4 main

from playLA.Matrix import Matrix
from playLA.Vector import Vector
from playLA.LinearSystem import LinearSystem


if __name__ == "__main__":

    A = Matrix([[1, 2, 4], [3, 7, 2], [2, 3, 3]])
    b = Vector([7, -11, 1])
    ls = LinearSystem(A, b)
    ls.gauss_jordan_elimination()
    ls.fancy_print()
    print()
    # [-1, -2, 3]

    A2 = Matrix([[1, -3, 5], [2, -1, -3], [3, 1, 4]])
    b2 = Vector([-9, 19, -13])
    ls2 = LinearSystem(A2, b2)
    ls2.gauss_jordan_elimination()
    ls2.fancy_print()
    print()
    # [2, -3, -4]

    A3 = Matrix([[1, 2, -2], [2, -3, 1], [3, -1, 3]])
    b3 = Vector([6, -10, -16])
    ls3 = LinearSystem(A3, b3)
    ls3.gauss_jordan_elimination()
    ls3.fancy_print()
    print()
    # [-2, 1, -3]

    A4 = Matrix([[3, 1, -2], [5, -3, 10], [7, 4, 16]])
    b4 = Vector([4, 32, 13])
    ls4 = LinearSystem(A4, b4)
    ls4.gauss_jordan_elimination()
    ls4.fancy_print()
    print()
    # [3, -4, 0.5]

    A5 = Matrix([[6, -3, 2], [5, 1, 12], [8, 5, 1]])
    b5 = Vector([31, 36, 11])
    ls5 = LinearSystem(A5, b5)
    ls5.gauss_jordan_elimination()
    ls5.fancy_print()
    print()
    # [3, -3, 2]

    A6 = Matrix([[1, 1, 1], [1, -1, -1], [2, 1, 5]])
    b6 = Vector([3, -1, 8])
    ls6 = LinearSystem(A6, b6)
    ls6.gauss_jordan_elimination()
    ls6.fancy_print()
    print()
    # [1, 1, 1]

    A7 = Matrix([[1, -1, 2, 0, 3],
                 [-1, 1, 0, 2, -5],
                 [1, -1, 4, 2, 4],
                 [-2, 2, -5, -1, -3]])
    b7 = Vector([1, 5, 13, -1])
    ls7 = LinearSystem(A7, b7)
    ls7.gauss_jordan_elimination()
    ls7.fancy_print()
    print()

    A8 = Matrix([[2, 2],
                 [2, 1],
                 [1, 2]])
    b8 = Vector([3, 2.5, 7])
    ls8 = LinearSystem(A8, b8)
    if not ls8.gauss_jordan_elimination():
        print("No Solution!")
    ls8.fancy_print()
    print()

    A9 = Matrix([[2, 0, 1],
                 [-1, -1, -2],
                 [-3, 0, 1]])
    b9 = Vector([1, 0, 0])
    ls9 = LinearSystem(A9, b9)
    if not ls9.gauss_jordan_elimination():
        print("No Solution!")
    ls9.fancy_print()
    print()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1195120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一章 Object-XML 映射简介

文章目录 第一章 Object-XML 映射简介基础如何工作的映射选项IRIS 中的相关工具XML 文档的可能应用 第一章 Object-XML 映射简介 基础 将对象映射到 XML 一词意味着定义如何将该对象用作 XML 文档。要将对象映射到 XML&#xff0c;请将 %XML.Adaptor 添加到定义该对象的类的超…

一题三解(暴力、二分查找算法、单指针):鸡蛋掉落

涉及知识点 暴力、二分查找算法、单指针 题目 给你 k 枚相同的鸡蛋&#xff0c;并可以使用一栋从第 1 层到第 n 层共有 n 层楼的建筑。 已知存在楼层 f &#xff0c;满足 0 < f < n &#xff0c;任何从 高于 f 的楼层落下的鸡蛋都会碎&#xff0c;从 f 楼层或比它低的…

基于51单片机的万年历-脉搏计仿真及源程序

一、系统方案 1、本设计采用51单片机作为主控器。 2、DS1302采集年月日时分秒送到液晶1602显示。 3、按键年月日时分秒&#xff0c;心率报警上下限。 4、红外对接管传感器采集心率送到液晶1602显示。 5、心率低于下限或高于上限&#xff0c;蜂鸣器报警。 二、硬件设计 原理图如…

18 Linux 阻塞和非阻塞 IO

一、阻塞和非阻塞 IO 1. 阻塞和非阻塞简介 这里的 IO 指 Input/Output&#xff08;输入/输出&#xff09;&#xff0c;是应用程序对驱动设备的输入/输出操作。当应用程序对设备驱动进行操作的时候&#xff0c;如果不能获取到设备资源&#xff0c;那么阻塞式 IO 就会将对应应用…

一台电脑使用多个gitee账号,以及提交忽略部分文件

目录 ​编辑 一&#xff1a;前言 二&#xff1a;解决方法 三&#xff1a;提交gitee时忽略文件 一&#xff1a;前言 在开发中&#xff0c;我们拥有不止一个 gitee 账号&#xff0c;通常而言一个是公司的&#xff0c;一个是私人的。有时候我们在公司写了一些自己的东西&#…

GS3661V1 3.7升压5V 3A SOT23-5封装 外置MOS 升压芯片 单节锂电升压5V 2.5-3A

GS3661V1 3.7升压5V 3A SOT23-5 外置MOS 升压芯片 单节锂电升压5V 2.5-3A

全新Inner-IoU损失函数!!!通过辅助边界框计算IoU有效提升检测效果

摘要 1 简介 2 方法 2.1 边界框回归模式分析 2.2 Inner-IoU 损失 3 实验 3.1 模拟实验 3.2 对比实验 3.2.1 PASCAL VOC上的YOLOv7 3.2.2 YOLOv5 在 AI-TOD 上 4. 参考 摘要 随着检测器的快速发展&#xff0c;边界框回归&#xff08;BBR&#xff09;损失函数不断进…

【赠书第3期】用ChatGPT轻松玩转机器学习与深度学习

文章目录 前言 1 机器学习 2 深度学习 3 使用ChatGPT进行机器学习和深度学习 4 推荐图书 5 粉丝福利 前言 机器学习和深度学习是当前最热门的技术领域之一&#xff0c;这些技术正在不断地改变我们的生活和工作方式。ChatGPT 是一款基于大规模预训练模型的自然语言处理工…

C4D vs Blender:哪个更适合你的需求?

对于初学者来说&#xff0c;选择合适的 3D 制作软件往往是一件很困扰的事情。近年来&#xff0c;C4D 和 Blender 成为了许多动画和 3D 建模爱好者的热门选择。那么&#xff0c;这两款软件各有什么特色呢&#xff1f;让我们一起来看看吧&#xff01; 一、软件特色 C4D 是一款商…

GEE ——errors & debuggings (2023GEE峰会总结)

简介&#xff1a; 在gee中有三种错误&#xff0c;一种就是系统错误&#xff0c;也就是我们看到的会在JavaScript code editor中出现的错误&#xff0c;也就是在程序还没有启动之前就会提示的错误&#xff0c;而客户端错误则主要是会提示一些在代码过程中的错误&#xff0c;比如…

Java语言基础(上)

Java 语言的特点 面对对象&#xff1a;Java 中所有的数据和方法都封装在对象中跨平台性&#xff1a;Java 通过 Java 虚拟机&#xff0c;可以在不同的操作系统上运行相同的程序自动内存管理&#xff1a;Java 提供垃圾回收机制&#xff0c;不需要手动管理内存强类型语言&#xf…

ElasticSearch7.x - HTTP 操作 - 索引操作

创建索引 对比关系型数据库,创建索引就等同于创建数据库 在 Postman 中,向 ES 服务器发 PUT 请求 :http://192.168.254.101:9200/shopping 说明 {"acknowledged"【响应结果】: true, # true 操作成功"shards_acknowledged"【分片结果】: true, # 分片操…

亚数受邀参加“长三角G60科创走廊量子密码应用创新联盟(中心)”启动仪式

11月8日&#xff0c;在第六届中国国际进口博览会2023长三角G60科创走廊高质量发展要素对接大会上&#xff0c;亚数信息科技&#xff08;上海&#xff09;有限公司CEO翟新元作为密码企业代表之一受邀参加“长三角G60科创走廊量子密码应用创新联盟&#xff08;中心&#xff09;”…

【手动创建UIWindow Objective-C语言】

一、上节课,我们讲了控制器View的懒加载: 1.什么时候会调用这个懒加载呢,用我们直接,控制器self.view self.view的时候: 什么时候,调用它这个self.view, 就要去加载控制器的view, self.view 加载控制器的view 我们给大家演示过了,这个大家已经清楚了,我们给大家说…

2023年A股借壳上市研究报告

第一章 借壳上市概况 1.1 定义 借壳上市作为一种独特的资本市场操作手法&#xff0c;历来是企业拓展融资渠道和实现市场战略目标的重要途径。具体来说&#xff0c;借壳上市可分为狭义与广义两种模式。在狭义的定义下&#xff0c;借壳上市是指一家已上市的公司的控股母公司&am…

vivo 数据库降本实践:探索成本效益最优的数据库解决方案

vivo 自 2022 年开始调研、测试 OceanBase 至今&#xff0c;现已上线 17 个业务系统&#xff0c;涵盖日志类、分析类、交易类业务&#xff0c;实现了总资源节省 80%&#xff0c;开发、运维工作大幅简化。vivo 体系与流程 IT 部门数据库高级工程师廖光明在本文中&#xff0c;详细…

利用MSF设置代理

1、介绍&#xff1a; 通过MSF拿到一个机器的权限后&#xff0c;通过MSF搭建socks代理&#xff0c;然后通内网。 拿到目标权限&#xff0c;有很多方法&#xff0c;比如&#xff1a;①ms17-010 ②补丁漏洞 ③MSF生成后门 在此直接使用MSF生成后门 MSF中有三个代理模块&#x…

【Kurbernetes部署】知识点总结(部署方式、网络插件.....)

知识点合集 一、Kurbernetes常见的部署方式1.1 Minikube&#xff08;一般不用&#xff09;1.2 Kubeadm1.3 二进制安装部署&#xff08;推荐使用的方式&#xff09; 二、二进制部署Kurbetnetes的思路Step1 部署etcdStep2 部署master组件Step3 部署node组件Step4 部署多master高可…

leetcode:160. 相交链表

一、题目 原题链接&#xff1a;160. 相交链表 - 力扣&#xff08;LeetCode&#xff09; 函数原型&#xff1a; struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 二、思路 判断两个链表是否相交&#xff0c;只要判断两个链表是否有相同的…

3 分钟看完 NVIDIA GPU 架构及演进

近期随着 AI 市场的爆发式增长&#xff0c;作为 AI 背后技术的核心之一 GPU&#xff08;图形处理器&#xff09;的价格也水涨船高。GPU 在人工智能中发挥着巨大的重要&#xff0c;特别是在计算和数据处理方面。目前生产 GPU 主流厂商其实并不多&#xff0c;主要就是 NVIDIA、AM…