矩阵的魅力

在线性代数中,我们学习了过行列式,矩阵,向量等,用于求解线性方程组的解,基础解系,特征值及特征向量等。可这些有什么用呢?(在文末会给出应用)

先来了解矩阵的特性 

定义:一个m行n列的数表组合而成称为m×n的句子,当m=n时,矩阵A称为n阶矩阵或n阶方阵

基本性质:

 一般在考研数学中会让计算矩阵的秩,矩阵的逆,矩阵(方阵才有特征值和特征向量),求伴随矩阵等等,下面先通过讲解最基本的矩阵表达,再深入。

在C语言中创建矩阵需要循环遍历每一行,每一列,即用二维数组来表示(n×n)

例如矩阵A

如果用c语言进行编译的话

#include <stdio.h>
#define N 3 // 矩阵的维度

int main() {
    // 定义并初始化矩阵 A
    int A[N][N] = 
	{
        {1, 1, -1},
        {1, -2, 2},
        {-3, 1, 3}
    };
    // 打印矩阵 A
    printf("矩阵 A:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) 
		{
            printf("%d ", A[i][j]);
        }
        printf("\n");
    }

    return 0;
}

对于matlab和python是[  ],而c语言是{ },且c语言打印矩阵非常不方便,需要使用多层嵌套循环才可,所以不推荐矩阵运算使用C语言。
那么开始matlab的矩阵学习

(2)函数创建法

MATLAB提供了一些函数,这些函数可以用来生成某些特定的矩阵,我们这里介绍几组最常用到的函数。

第一组函数: zeros、ones和eye。这三个函数分别用来创建全为0的矩阵、全为1的矩阵和单位矩阵。

以zeros函数为例,其常见的用法有两种:(1)zeros(n)可以创建一个n行n列全为0的矩阵;(2)zeros(m,n)可以创建一个m行n列全为0的矩阵。eye的用法类似。

% 创建一个 3x3 的单位矩阵
A = eye(3);

% 创建一个 2x4 的矩阵,主对角线上的元素为 1,其余元素为 0
B = eye(2, 4);

% 创建一个 3x3 的矩阵,将第 1 条上对角线(即主对角线以上的对角线)上的元素设为 1,其余元素为 0
C = eye(3, 3, 1);

生成了矩阵,或者我们提前定义好了矩阵,最重要的是,如何得到矩阵的信息是关键的,我们可以利用线性索引来取出矩阵中的元素,尽管这种方式并不那么直观。

例如还是这个矩阵A = [1, 1, -1; 1, -2, 2; -3, 1, 3];(在matlab中","英文半角逗号相当于个隔行,也可以用空格代替,;分号是换行的意思,A = [1 1 -1; 1 -2 2; -3 1 3];最后的分号不加就直接打印出来,不显示在工作区里)

A(1,2)%第一行第二列的元素

A(2,end)%第二行最后一列的元素

A(2,[1 3])%第二行、第一三列的元素

%例如A(4)=1,A(2:3) =1 -3 1

%取出 A 的第2,3两列的元素A(:,[2,3]),取出 A 的最后一列的元素A(: , end)

A(:, n) %表示矩阵A的第n列的所有元素。

A(:, n) %表示矩阵A的第n列的所有元素。

A(:)%命令可以将A中的所有元素按照线性索引的顺序重构成一个列向量。

矩阵也可以进行横向拼接,类似于增广矩阵(A|b)和求逆时(A|E),用[A, B]

也可以纵向拼接,用[A; B]

关于矩阵相乘最重要的就是主要维度,s×n与n×p前一个矩阵的列和后一个矩阵行数相同才行,不然会报错。

下面这段代码可以得到矩阵A的转置,伴随,可逆矩阵,秩,行列式的值,特征值及特征向量

function juzhenjisuan()  %后续需要调用,可跨文件调用,不过要放在同一文件夹下
    % 创建一个 4x4 的零矩阵 B
    B = zeros(4, 4);
    
    % 使用随机整数填充矩阵 B
    for i = 1:4
        for j = 1:4
            B(i, j) = randi([0, 10]); 
        end
    end
    fprintf('随机生成矩阵B:\n');
    disp(B);
    
    % 定义矩阵 A
    A = [1, 1, -1; 1, -2, 2; -3, 1, 3];
    
    % 计算矩阵 A 的秩
    zhi = rank(A);
    
    % 计算矩阵 A 所有元素的和
    sumA = sum(A, 'all');
  
    % 输出矩阵 A
    fprintf('原始矩阵:\n');
    disp(A);
    
    % 输出矩阵 A 的转置矩阵
    fprintf('矩阵的转置:\n');
    disp(A');
    
    % 输出矩阵 A 的秩
    fprintf('矩阵的秩:%d\n', zhi);
    
    % 输出矩阵 A 所有元素的和
    fprintf('矩阵求和:%d\n', sumA);

    % 计算矩阵 A 的行列式
    detA = det(A);
    fprintf('矩阵的行列式:%f\n', detA);

    % 计算矩阵 A 的逆矩阵
    if detA ~= 0
        A_inv = inv(A);
        fprintf('矩阵的逆:\n');
        disp(A_inv);
    else
        fprintf('矩阵 A 是奇异矩阵,没有逆矩阵。\n');
    end

    % 计算矩阵 A 的伴随矩阵
    A_adj = bansui(A);
    fprintf('矩阵的伴随矩阵:\n');
    disp(A_adj);

    % 计算矩阵 A 的特征值和特征向量
    [V, D] = eig(A);
    
    % 输出矩阵 A 的特征值
    tezhengvalues = diag(D);  
    fprintf('矩阵的特征值:\n');
    disp(tezhengvalues);
    
    % 输出特征向量
    for i = 1:length(tezhengvalues)
        fprintf('当特征值为 %f 时,一个特征向量为:\n', tezhengvalues(i));
        disp(V(:, i));
    end
end

% 计算伴随矩阵
function A_adj = bansui(A)
    % 获取矩阵的大小
    [n, ~] = size(A);
    
    % 初始化伴随矩阵
    A_adj = zeros(n, n);
    
    % 计算伴随矩阵
    for i = 1:n
        for j = 1:n
            % 计算余子式的代数余子式
            M = A;
            M(i, :) = [];
            M(:, j) = [];
            A_adj(j, i) = (-1)^(i+j) * det(M);
        end
    end
end

以上都是线性代数中学过的,下面才是重头戏,也是矩阵最具魅力的时刻:

矩阵翻转:

fliplr矩阵左右翻转
flipud矩阵上下翻转
triu 矩阵的上三角部分
tril矩阵的下三角部分
diag对角矩阵
full将稀疏矩阵化为普通矩阵
sparse生成稀疏矩阵
randn生成正态分布随机矩阵
% 定义矩阵 A
A = [1, 1, -1; 1, -2, 2; -3, 1, 3];

% 顺时针旋转 90°
A_cw_90 = rot90(A, -1);

% 逆时针旋转 90°
A_ccw_90 = rot90(A);

% 以主对角线为轴翻转
A_main_diag_flip = A';

% 以副对角线为轴翻转
A_anti_diag_flip = rot90(A,2);

% 左右翻转
A_horizontal_flip = fliplr(A);

% 上下翻转
A_vertical_flip = flipud(A);

% 中心翻转
A_center_flip = rot90(A,2);

% 显示结果
disp('顺时针旋转 90°:');
disp(A_cw_90);

disp('逆时针旋转 90°:');
disp(A_ccw_90);

disp('以主对角线为轴翻转:');
disp(A_main_diag_flip);

disp('以副对角线为轴翻转:');
disp(A_anti_diag_flip);

disp('左右翻转:');
disp(A_horizontal_flip);

disp('上下翻转:');
disp(A_vertical_flip);

disp('中心翻转:');
disp(A_center_flip);

那么矩阵为什么要进行翻转操作呢?

例如在卷积操作中,卷积核翻转是为了符合卷积的数学定义。卷积操作的定义要求在每个位置计算加权和时,卷积核要与信号对齐。翻转卷积核保证了计算的准确性。如果不进行翻转,你实际上是在执行相关操作,这与卷积的标准定义不同,因此得到的结果也会不同。在实际应用中,卷积的翻转保证了运算的一致性和数学正确性。

出现差异的本质原因是:数学中的卷积和卷积神经网络中的卷积严格意义上是两种不同的运算。
卷积核与原始的矩阵乘积,是围绕着中心元素进行180度旋转后,才是对应的元素。

(一般来说图像处理里的卷积核不需要进行翻转操作,信号处理是需要翻转的--经验)

矩阵卷积:

在卷积神经网络的卷积层中,

\begin{aligned}y[n_{1},n_{2}]&=x[n_1,n_2]*h[n_1,n_2]\\&=\sum_{m_1=-\infty}^\infty\sum_{m_2=-\infty}^\infty x[m_1,m_2]\cdot h[n_1-m_1,n_2-m_2]\end{aligned}

聪明的友友应该能发现这里卷积核已经进行翻转后,所以这个公式的意义说实话意义不大,而且在python中已有函数例如tensorFlow中的conv2d()可以调用,自动进行翻转了。

最后,矩阵在生活中无处不在,他的应用非常广泛,在三维建模,多维空间变换(旋转矩阵),深度学习,计算机视觉,图像处理(像素点本质就是矩阵构成的,RGB三维通道)等。

例如在工业机器人求解逆运动学问题时,速度雅可比矩阵是一个至关重要的工具,它建立了机器人关节速度与末端执行器速度之间的线性映射关系。同样地,力雅可比矩阵则是速度雅可比矩阵的转置,用于描述末端执行器受到的力与关节力矩之间的映射关系。

求解逆运动学问题就是建立末端执行器的位姿求解关节变量(RPY角)的过程,本质上是对旋转矩阵的叠加(左乘,绕固定坐标系)的解算,它可以用于迭代方法(如牛顿-拉弗森法)中,通过逐步调整关节角度来逼近目标位置。

  • 奇异性:当雅可比矩阵的行列式接近零时,机器人处于奇异位形,此时关节速度或力矩的微小变化可能导致末端执行器速度的巨大变化或无法控制的运动。(也就是机械原理里的死点位置,压力角=90°)

图像处理中的特征向量

  1. 定义:

    • 在图像处理中,特征向量通常指的是从图像数据中提取出的描述图像主要特征的向量。这些特征向量可能由各种特征提取方法获得,如主成分分析(PCA)、尺度不变特征变换等。
  2. 应用:

    • 图像处理中的特征向量用于图像分类、物体识别、图像检索等任务。这些特征向量通常是对图像的某些特性(如纹理、形状、颜色等)的紧凑描述。

第3章 3.3 MATLAB中的矩阵(MATLAB入门课程)_matlab矩阵-CSDN博客

MATLAB:矩阵(基础知识)_matlab 矩阵-CSDN博客

矩阵卷积运算的具体过程,很简单_两个三阶矩阵卷积怎么算-CSDN博客

深入理解卷积(卷积核到底要不要翻卷)_卷积核翻转-CSDN博客

  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值