拟合平面再思考

0。总结

之前思考了2种拟合平面的方式

1。ransan 随机取样拟合平面

2。特征值分解特征向量,最小特征值就是法向量

其中方法一误差较小,毕竟随机采样的方式可以忽略误差点。而特征值分解的方式如果误差较大,那么得到的结果非常不好

1。扩展

https://www.ilikebigbits.com/2015_03_04_plane_from_points.html

这篇文章说,通过求协方差矩阵就可以更好的拟合平面

这个文章的重点是他假设c=1 也就是c不能等于0。也就是平面的法向量的z轴不能为0

然后求得 a b d 这样就求得了平面方程

ax+by+cz+d=0

但是看代码发现他还要求的最大值?

这是为了避免假设不成立。所以他计算了3次。

假设a=1 ,假设b=1 ,假设c=1。通过这种方式求了3次。获取最大值保证法向量的xyz轴分量假设不为0的情况

然后求得法向量

但是这个法向量和通过协方差矩阵求的还是有差异。具体的取舍就看大家了

2。代码

python 复制代码
def getplanefrompoints(points):
    centroid = np.mean(points, axis=0)

    r = points - centroid

    xx = np.sum(r[:, 0] * r[:, 0])
    xy = np.sum(r[:, 0] * r[:, 1])
    xz = np.sum(r[:, 0] * r[:, 2])
    yy = np.sum(r[:, 1] * r[:, 1])
    yz = np.sum(r[:, 1] * r[:, 2])
    zz = np.sum(r[:, 2] * r[:, 2])

    det_x = yy * zz - yz * yz
    det_y = xx * zz - xz * xz
    det_z = xx * yy - xy * xy

    if det_x > det_y and det_x > det_z:
        vecC = (det_x, xz * yz - xy * zz, xy * yz - xz * yy)
    elif det_y > det_z:
        vecC = (xz * yz - xy * zz, det_y, xy * xz - yz * xx)
    else:
        vecC = (xy * yz - xz * yy, xy * xz - yz * xx, det_z)

    vecC = vecC / np.linalg.norm(vecC)

    d = -vecC.dot(centroid)
    return vecC

3。特征值求解原理

3。1 jacobi

Jacobi 方法是一种迭代法,用于计算对称矩阵的特征值和特征向量。它的基本思想是通过一系列相似变换,逐步将对称矩阵对角化,使得非对角线上的元素逐渐趋于零。以下是 Jacobi 方法的基本原理:

  1. 选择旋转角度: 在每一次迭代中,Jacobi 方法会选择一个最大的非对角线元素,然后计算旋转角度。旋转角度的选择有多种方法,一种常见的是选取使得旋转后的非对角线元素为零的角度。

  2. 构造旋转矩阵: 利用选择的旋转角度,构造一个旋转矩阵。这个旋转矩阵是一个正交矩阵,它的转置等于它的逆。

  3. 相似变换: 将原矩阵通过相似变换,即左乘和右乘旋转矩阵,得到一个新的矩阵。这个新矩阵在对角线上的元素更接近特征值。

  4. 迭代: 重复以上步骤,直到矩阵的非对角线元素足够小,或者达到预定的迭代次数。

Jacobi 方法的优点是简单易懂,容易实现,并且适用于小型矩阵。然而,它的缺点是收敛速度相对较慢,尤其是对于大型矩阵。在实际应用中,更高效的算法(如QR分解、Lanczos 方法等)通常会被使用,以便更快地计算特征值和特征向量。

3。2对角化

对角化是线性代数中的一个重要概念,它涉及将一个矩阵转换为对角矩阵的过程。对角化使得矩阵的很多运算变得更加简单,特别是计算矩阵的幂次、矩阵指数和矩阵函数等操作。

对于一个 (n \times n) 的方阵 (A),如果存在一个可逆矩阵 (P) 使得 (P^{-1}AP) 是一个对角矩阵,即:

P\^{-1}AP = D

其中,(D) 是一个对角矩阵,其对角线上的元素是 (A) 的特征值。这样的矩阵 (P) 被称为 (A) 的特征向量矩阵,而 (D) 则是 (A) 的特征值矩阵。

对角化的步骤如下:

  1. 计算特征值: 找到矩阵 (A) 的特征值 (\lambda).

  2. 计算特征向量: 对于每个特征值,找到对应的特征向量 (\mathbf{v}).

  3. 构造矩阵 (P): 将特征向量按列排列成矩阵 (P).

  4. 对角化: 计算 (P^{-1}AP).

对角化的好处在于,对角矩阵的幂次运算非常简单,因为对角矩阵的幂次就是每个对角元素的幂次。这对于某些数值计算和线性代数的问题是非常有用的。

在实际应用中,对角化不一定对所有矩阵都可行。可对角化的矩阵被称为可对角化矩阵,而对于某些矩阵,它们可能不可对角化。

3。3对角矩阵

对角矩阵是一种特殊形式的矩阵,其中除了主对角线上的元素之外,所有其他元素都为零。一个 (n \times n) 的对角矩阵可以表示为:

D = \\begin{bmatrix} d_{1} \& 0 \& \\cdots \& 0 \\ 0 \& d_{2} \& \\cdots \& 0 \\ \\vdots \& \\vdots \& \\ddots \& \\vdots \\ 0 \& 0 \& \\cdots \& d_{n} \\end{bmatrix}

其中 (d_{1}, d_{2}, \ldots, d_{n}) 是对角线上的元素。

对角矩阵具有一些有趣的性质,使得它们在线性代数中非常有用。以下是一些关于对角矩阵的重要性质:

  1. 幂次运算简化: 对角矩阵的幂次运算非常简单。如果 (D) 是对角矩阵,那么 (D^k) 的每个对角元素就是 (d_{i}^k)。

  2. 特征值和特征向量: 对角矩阵的特征值就是它的对角元素,而每个对角元素本身就是对应的特征向量。

  3. 可逆性: 对角矩阵是可逆的当且仅当每个对角元素都不为零。

  4. 乘法和加法: 对角矩阵的乘法和加法操作都很简单,因为大部分元素都是零。

对角矩阵在许多数学和工程应用中经常出现,特别是在对角化矩阵的概念中。对角化是将一个矩阵转换为对角矩阵的过程,便于处理矩阵的一些运算。

3。4 python实现

python 复制代码
import numpy as np

def jacobi_eigenvalue(A, tol=1e-10, max_iter=1000):
    """
    Jacobi 方法求解对称矩阵的特征值和特征向量

    Parameters:
    - A: 对称矩阵
    - tol: 迭代收敛的容忍度
    - max_iter: 最大迭代次数

    Returns:
    - eigenvalues: 特征值数组
    - eigenvectors: 特征向量矩阵,每一列是对应的特征向量
    """

    n = A.shape[0]
    eigenvalues = np.diag(A).copy()  # 初始时取矩阵的对角线元素作为特征值的初始估计
    eigenvectors = np.eye(n)  # 初始化特征向量矩阵为单位矩阵

    iter_count = 0
    while iter_count < max_iter:
        # 找到最大的非对角元素
        max_off_diag = np.max(np.abs(np.triu(A, k=1)))
        if max_off_diag < tol:
            break  # 收敛条件

        # 找到最大非对角元素的位置
        indices = np.where(np.abs(A) == max_off_diag)
        i, j = indices[0][0], indices[1][0]

        # 计算旋转角度
        if A[i, i] == A[j, j]:
            theta = np.pi / 4
        else:
            theta = 0.5 * np.arctan(2 * max_off_diag / (A[i, i] - A[j, j]))

        # 构造旋转矩阵
        rotation_matrix = np.eye(n)
        rotation_matrix[i, i] = np.cos(theta)
        rotation_matrix[j, j] = np.cos(theta)
        rotation_matrix[i, j] = -np.sin(theta)
        rotation_matrix[j, i] = np.sin(theta)

        # 进行相似变换
        A = rotation_matrix.T @ A @ rotation_matrix
        eigenvectors = eigenvectors @ rotation_matrix

        iter_count += 1

    return eigenvalues, eigenvectors

# 生成一个对称矩阵作为例子
A = np.array([[4.0, -2.0, 2.0],
              [-2.0, 2.0, -4.0],
              [2.0, -4.0, 11.0]])

eigenvalues, eigenvectors = jacobi_eigenvalue(A)
print("Eigenvalues:")
print(eigenvalues)

print("\nEigenvectors:")
print(eigenvectors)
相关推荐
索迪迈科技1 小时前
Flink Task线程处理模型:Mailbox
java·大数据·开发语言·数据结构·算法·flink
元亓亓亓2 小时前
LeetCode热题100--230. 二叉搜索树中第 K 小的元素--中等
算法·leetcode·职场和发展
草莓熊Lotso2 小时前
《算法闯关指南:优选算法-双指针》--01移动零,02复写零
c语言·c++·经验分享·算法·leetcode
焜昱错眩..3 小时前
代码随想录算法训练营第三十九天|62.不同路径 63.不同路径ll
算法
焦耳加热6 小时前
阿德莱德大学Nat. Commun.:盐模板策略实现废弃塑料到单原子催化剂的高值转化,推动环境与能源催化应用
人工智能·算法·机器学习·能源·材料工程
CodeCraft Studio6 小时前
PDF处理控件Aspose.PDF教程:使用 Python 将 PDF 转换为 Base64
开发语言·python·pdf·base64·aspose·aspose.pdf
wan5555cn6 小时前
多张图片生成视频模型技术深度解析
人工智能·笔记·深度学习·算法·音视频
u6067 小时前
常用排序算法核心知识点梳理
算法·排序
困鲲鲲7 小时前
Python中内置装饰器
python
摩羯座-185690305948 小时前
Python数据可视化基础:使用Matplotlib绘制图表
大数据·python·信息可视化·matplotlib