【MATLAB初阶】矩阵操作(二):矩阵的运算

🎬 博主名称键盘敲碎了雾霭
🔥 个人专栏 : 《C语言》《数据结构》 《C++》 《Matlab》 《Python》

⛺️指尖敲代码,雾霭皆可破


文章目录

  • 一、调用函数
    • [1.1 sum](#1.1 sum)
    • [1.2 prod](#1.2 prod)
    • [1.3 cumsum](#1.3 cumsum)
    • [1.4 diff](#1.4 diff)
    • [1.5 mean与mode](#1.5 mean与mode)
    • [1.6 median](#1.6 median)
    • [1.7 var与std](#1.7 var与std)
    • [1.8 min与max](#1.8 min与max)
    • [1.9 mink、maxk和topkrows](#1.9 mink、maxk和topkrows)
  • 二、算术运算
    • [2.1 兼容模式](#2.1 兼容模式)
    • [2.2 加法与减法](#2.2 加法与减法)
    • [2.3 乘法](#2.3 乘法)
    • [2.4 除法](#2.4 除法)
    • [2.5 乘方](#2.5 乘方)
  • 三、关系运算
  • 四、逻辑运算
    • [4.1 常见用法](#4.1 常见用法)
    • [4.2 利用逻辑值对矩阵进行索引](#4.2 利用逻辑值对矩阵进行索引)
    • [4.3 缺失值的识别和填补](#4.3 缺失值的识别和填补)
    • [4.4 all、any 和 find 函数](#4.4 all、any 和 find 函数)
  • 五、运算符优先级
  • 六、集合运算
    • [6.1 unique](#6.1 unique)
    • [6.2 ismember](#6.2 ismember)
    • [6.3 模拟中彩票](#6.3 模拟中彩票)
    • [6.4 intersect、union、setdiff和setxor函数](#6.4 intersect、union、setdiff和setxor函数)
    • [6.5 线性代数相关的函数](#6.5 线性代数相关的函数)
  • 文章结语

一、调用函数

我们会常见的数学运算函数(abs,sin,round,log),这些函数可以直接应用到矩阵上,所表示的含义是:对矩阵中的每个元素分别运用这些数学运算函数,返回的结果也是一个矩阵

前面的知识不会的参考这篇

【matlab初阶】matlab入门知识
https://blog.csdn.net/2401_89538720/article/details/159833837?fromshare=blogdetail&sharetype=blogdetail&sharerId=159833837&sharerefer=PC&sharesource=2401_89538720&sharefrom=from_link

这一节将学习以下函数

1.1 sum

  • 如果A是一个向量,则sum(A)可以计算A中所有元素的和
matlab 复制代码
A = 1:100
sum(A)
  • 如果A是一个矩阵,则sum(A,dim)可以计算A沿维度 dim 中所有元素的和
    (sum(A) % dim=1时可以不写)
  • 计算一个矩阵中所有元素的总和
matlab 复制代码
sum(sum(A))  % 计算每一列的和,返回一个行向量,然后再计算这个行向量的和
A(:) % 把A按照列拼接成一个向量
sum(A(:))% sum(A,'all')
  • 指定如何处理 NaN 值
    默认情况下,如果计算时有一个元素为NaN,那么最终会返回NaN;
    我们可以在最后加一个输入参数: 'omitnan', 这样就会忽略NaN
matlab 复制代码
A = [1 5 NaN 10];  % 向量中存在NaN
sum(A,'omitnan')

sum()对多个维度执行运算,一次对输入数组的多个维度执行运算。指定一个由运算维度组成的向量,或指定 "all" 选项以对所有数组维度执行运算

matlab 复制代码
a = randi(10,3,4)
sum(a,"all")  % 双引号表示字符串
sum(a,'all')  % 单引号表示字符向量
sum(a,[1,2])
sum(sum(a))
sum(a(:))

1.2 prod

prod函数的用法和sum函数的用法相同,它是用来计算乘积的

matlab 复制代码
v = [2,4,5,1,10];  % 向量
prod(v)  % 直接向量中所有元素的乘积 
v = 1:10; 
prod(v)  % 计算10的阶乘

1.3 cumsum

  • 如果A是一个向量,则cumsum(A)可以计算向量A的累积和(累加值)
matlab 复制代码
A = [1 5 3 4 -5 0 8];
cumsum(A)
  • 如果A是一个矩阵,则cumsum(A,dim)可以计算A沿维度 dim 中所有元素的累积和,具体的使用方法和sum函数类似。
matlab 复制代码
A = randi(10,3,4)
% 计算每一列的累积和
cumsum(A)  % 或者写成cumsum(A,1)
% 计算每一行的累积和
cumsum(A,2)
  • 也可以在最后加一个输入参数: 'omitnan', 这样计算时会忽略NaN。
    具体用法跟前面一样

1.4 diff

  • MATLAB中计算差分的函数是diff,我们可以使用diff(A,n)命令计算向量A的n阶差分,当n等于1时,可以直接写成diff(A)
matlab 复制代码
w = [60 65 66 70 68 72 64 70];
diff(w)  % 1阶差分, diff(w,1)
diff(w,2)  % 2阶差分
diff(w,3)  % 3阶差分
  • diff函数也可以用在矩阵上面:diff(A,n,dim)表示沿矩阵A的维度dim方向上计算差分,当dim=1时沿着行方向计算,即得到每列的n阶差分;当dim=2时沿着列方向计算,即得到每行的n阶差分。类似的,dim=1时,diff(A,n,1)也可以简写成diff(A,n).
matlab 复制代码
A = randi(10,3,4)
% 计算每列的1阶差分
diff(A)  % 也可写成diff(A,1)或diff(A,1,1)
% 计算每列的2阶差分
diff(A,2) % 也可写成diff(A,2,1)  
% 计算每行的1阶差分
diff(A,1,2) 
% 计算每行的2阶差分
diff(A,2,2)

注意,diff函数不支持使用'omitnan'参数来忽略向量或者矩阵中的NaN值。

1.5 mean与mode

  • 如果A是一个向量,则mean(A)可以计算向量A的平均值。
matlab 复制代码
y = [1 3 5 7 9];
mean(y)
  • 如果A是一个矩阵,则mean(A,dim)可以计算A沿维度dim中所有元素的平均值。
    当dim=1时沿着行方向计算,即得到每列的平均值;
    当dim=2时沿着列方向计算,即得到每行的平均值。
    类似的,dim=1时,mean(A,1)也可以简写成mean(A).

可以在最后加一个输入参数: 'omitnan', 这样计算时会忽略NaN。


  • mode
  • 向量A的众数
    直接调用mode(A)会返回A中出现次数最多的值。如果有多个值以相同的次数出现,mode函数将返回其中最小的值
matlab 复制代码
A = [2 3 -1 2 1 3];
mode(A)  
  • 如果A是一个矩阵
    则mode(A,1)或者mode(A)可以沿着行方向进行计算,得到每一列的众数;mode(A,2)可以沿着列方向进行计算,得到每一行的众数,这里的1和2表示维度dim。
    注意:使用mode函数计算众数时会自动忽略NaN值,我们不能额外添加'omitnan'参数,否则会报错。

    M,F,C\] = mode(A),mode可以有多个返回值,**M为MATLAB会返回最小的那个数作为众数** ,**F表示众数M在向量A中出现的次数** ,**C是一个元胞数组**,元胞数组里面有一个列向量,列向量中的每个元素都是向量A的众数,胞数组是使用大括号{}括起来的,元胞数组(cell array)里面的元素可以包含不同的数据类型,例如标量、向量、矩阵、字符串等

median函数可以用来计算中位数,它的使用方法和mean函数类似

1.7 var与std

  • var
    方差就是用来描述这种离散程度的一个统计量,当两组数据的平均值相同时,方差较大的一组数据的离散程度更大。
    样本方差与总体方差
  • 如果A是一个向量,那么var(A, w)可以计算A的方差,当w=0时,表示计算样本方差,w=1时表示计算总体方差,另外,var(A, 0)也可以直接简写为var(A)。
  • 如果A是一个矩阵,则var(A, w, dim)可以计算矩阵A沿维度dim上的方差。
    dim = 1时表示沿着行方向进行计算,即得到每一列的方差;
    dim = 2时表示沿着列方向进行计算,即得到每一行的方差。
    如果数据中存在NaN值,可以在var函数的最后加上'omitnan'参数来忽略NaN.
matlab 复制代码
v = [6 8 10 12 14];  
var(v)  % 样本方差,等价于var(v,0)
var(v,1)  % 总体方差
% 下面看矩阵的例子
A = randi(10,4,5)
var(A)  % 每一列的样本方差
% 也可以写成var(A,0)或者var(A,0,1) 
var(A,0,2)  % 每一行的样本方差
A = [9  7    10  10  NaN;
10  NaN 10  5   10;
2   3    2   9   8;
10  6   10    2  10];  
% 矩阵中存在NaN值
var(A, 0, 2)  % 计算每一行的样本方差
% 忽略NaN值计算每一行的样本方差
var(A, 0, 2, 'omitnan')  

  • std
    标准差是方差的算术平方根,它也是用来反应数据离散程度的一个统计量。那么问题来了,既然有了方差为什么还需要标准差呢?这是因为方差和数据原本的量纲(即单位)是不一致的
    可以使用std函数计算样本标准差和总体标准差,它和var函数的使用方法完全相同

1.8 min与max

  • 求两个矩阵对应位置元素的最小值: min(A,B)
    矩阵A和矩阵B的大小可以不一样,只要保证矩阵A和矩阵B具有兼容的大小就能够计算
matlab 复制代码
A = randi(10,4,3)
B = 5;  % 例如B可以是一个标量(常数)
min(A,B)
  • 求向量或者矩阵中的最小值,可以指定沿什么维度计算并返回索引。
    • A是向量,则min(A)返回A中的最小值**。如果A中有复数,则比较的是复数的模长
matlab 复制代码
A = [5 6 7 3 5 3 10];
min(A)
B = [4.5  3+4i  6];
min(B)  
    • 如果A是矩阵
  • min(A, [ ], 1)沿着A的行方向求每一列的最小值,也可以简写为min(A);min(A, [ ], 2)沿着A的列方向求每一行的最小值。这里的1和2表示矩阵的维度(dim)。
    注意:中间要加一个空向量[ ]? 如果不加的话,就是将A中每个元素和1或者2比较大小,并返回较小值。
matlab 复制代码
A = randi(10,3,4)
min(A,[ ],1)  % 求每一列的最小值
% 可以简写成min(A)
min(A,[ ],2)  % 求每一行的最小值
  • 在求向量或矩阵的最小值时
    min函数可以有两个返回值:[m, ind] = min(A). 第一个返回值m是我们要求的最小值,ind是最小值在所在维度上的索引。如果最小元素出现多次,则 ind是最小值第一次出现位置的索引。

果向量或者矩阵中存在NaN值,min函数会自动忽略,大家不需要单独对NaN值进行处理。


max函数和min函数的用法相同,它是用来求最大值的函数。

1.9 mink、maxk和topkrows

  • mink、maxk
    如果A是一个向量,则mink(A,k)可以计算向量A的前k个最小值。
matlab 复制代码
A = [1,5,0,4,9,9,3,5,8];
mink(A,3)

如果A是一个矩阵,则mink(A,k,dim)可以计算A沿维度dim的前k个最小值。

当dim=1时沿着行方向计算,即得到每列的前k个最小值;

当dim=2时沿着列方向计算,即得到每行的前k个最小值。

maxk使用方法和mink类似


  • topkrows :返回矩阵按照排序顺序的前若干行
    这个函数的用法和上一节介绍的sortrows函数类似,sortrows函数基于某一列对整个矩阵进行排序,而topkrows函数则只返回排序后的前k行
    默认是降序排列 )。
matlab 复制代码
topkrows(x,3)
等价于
sx = sortrows(x,'descend');
sx(1:3,:)

二、算术运算

2.1 兼容模式

matlab 复制代码
A = randi(10,2,3)
B = randi(10,2,1)
A + B

2.2 加法与减法

前提:只要两个矩阵的大小兼容,就能够进行计算

MATLAB会将大小兼容的矩阵隐式扩展为相同的大小,然后再将对应位置的元素相加,这种计算方式在MATLAB中称为"按对应位置的元素运算"。
矩阵的减法也满足这种计算规则

2.3 乘法

  • 运算符号是乘号"*"
    例如矩阵A*B,矩阵的乘法必须要满足前面矩阵A的列数和后面矩阵B的行数相等;
  • 使用的运算符号是点乘 ".*"
    A.*B,这时A和B的大小只需要满足上方表格介绍的五种兼容模式。
matlab 复制代码
A = randi(10,2,3)
B = randi(10,2,3)
A .* B
A = randi(10,2,3)
B = randi(10,1,3)
A .* B

如果一个矩阵和常数相乘,那么使用乘号"*"和点乘".*"得到的结果相同

matlab 复制代码
x = randi(10,5)
y = 3;
x * y 
x.* y 

2.4 除法

我们线性代数中,矩阵并不能进行除法的运算,但MATLAB中定义了矩阵的除法的计算规则。

  • /(右除) 和 \(左除)
    可以把这个符号想象成一个梯子,梯子靠在哪边墙上就是哪边的除法
    /(右除),命令"x = B/A"表示对线性方程组x*A = B求解x;
matlab 复制代码
A = [2,8,2;
     5,-4,8;
     6,4,0];
B = [18,60,-6];
x = B / A   % [5 -2 3]
% 验算下:x*A是否等于B
x * A
matlab 复制代码
A = [1 5 8;
     2,4,9;
     3,0,2];
B = [10;
     4;
     -1];
x = A\B  % [1;5;-2]
% 验算下:A*x是否等于B
A * x
  • "./"点除
    命令"A ./ B"表示用A的每个元素除以B的对应元素,A和B的大小必须兼容;
matlab 复制代码
A = randi([0,10],3,2)
B = randi([0,10],3,2)
A ./ B  % 点右除
1 ./ A  % 对A中每个元素计算倒数
A./B

如果B是标量,那么A./B的结果和A/B的结果相同。

matlab 复制代码
A = randi(10,3)
B = 3;
A./B
A / B

2.5 乘方

  • "^"表示矩阵的幂运算
    A是一个方阵,那么A ^ 3等价于AA A
    ".^"表示对矩阵中的每一个元素分别进行乘方计算,例如A .^ 0.5表示对矩阵A中的每一个元素开根号
matlab 复制代码
A = randi(10,3,4)
A .^ 2  % 每个元素求平方,等价于 A .* A
A .* A
A .^ 0.5   % 每个元素开根号
sqrt(A)
A .^ (-1)   % 每个元素求倒数,等价于 1./ A 
1./ A 
  • 计算逆矩阵
    如果A是一个可逆的方阵,那么A^(-1)可用来计算A的逆矩阵(inverse matrix)。另外,MATLAB中的inv函数也可以计算逆矩阵,它们的计算结果相同。
matlab 复制代码
% 只有方阵才有逆矩阵的概念
A = [1 2 3;
    2 2 1;
    3 4 3]
B1 = A ^ (-1)
B2 = inv(A)

线性代数中逆矩阵的定义,互为逆矩阵的两个矩阵的乘积为单位矩阵,由于 MATLAB使用浮点数计算矩阵的逆存在一定的误差,因此,实际上 算出的接近但不完全等于单位矩阵。

矩阵的转置符号为英文的单引号:" ' ",它也可以在前面加上点变成" .' ",两者的区别在于对矩阵中复数的处理,使用" ' "会在转置的同时将复数变为共轭复数,使用".'"则会保持原来的复数。

matlab 复制代码
format short
A = [ 3     1+3i;
      2     5;
      4-2i  6];
A'
A.'

通常情况下我们的矩阵中全是实数,那么使用"'"和".'"的效果相同。

matlab 复制代码
A = randi(10,3,4)
A'
A.'

三、关系运算

关系运算符可以用来比较两个数组中元素的关系,如果结果为真,则MATLAB会返回逻辑值1 ;如果结果为假,则会返回逻辑值0

matlab 复制代码
A = randi(5,1,3)
B = randi(5,2,1)
A == B  

注意:NaN(不定值或缺失值)相互之间不相等
易错点:连续使用关系运算符

逻辑值1和逻辑值0不仅仅用于表示真true和假false,它们在进行计算时也可以被视为数值1和数值0

复制代码
x = randi(10, 3, 4)
y = x > 5
% 也可以写成y = (x>5),加括号会让运算的顺序更清晰
sum(y)  % 计算每一列的和
sum(y(:))  % 计算所有元素的个数
sum(x(y))%计算所有大于5的和

  • 判断浮点数是否相等
    使用容差 tol(而不是使用 ==)比较浮点数。
    例如:要比较A和B两个数是否相等,只需要满足:|A − B| ≤ tol ,这里的tol是一个非常非常小的正数,
    例如tol可以取成1e-12(10的-12次方)。tol越小,要求越严格。
matlab 复制代码
abs(C-0) <= 1e-12

四、逻辑运算

4.1 常见用法

函数名和对应的运算符可以执行相同的功能,除了"逻辑异或"没有相应的运算符外,剩下三个运算方法都有对应的运算符。

matlab 复制代码
A = [-5 1.2  0  0  3  5.9];
B = [0   4   1  0 1.5 -2 ];
A & B

MATLAB在进行逻辑运算之前,在计算机内部自动将数值转换成了逻辑值,我们也可以使用logical函数手动进行转换

matlab 复制代码
A = randi([-5,5],4,3)
logical(A)

true函数和false函数可分别用来生成全为逻辑1和逻辑0的逻辑矩阵。

matlab 复制代码
true(2)  % 等价于logical(ones(2))
false(2,3)  % 等价于logical(zeros(2,3))
matlab 复制代码
A = randi([-3,3],2,4)
B = randi([-3,3],1,4)
B | 0
A | B
~A
xor(3,4)
xor(A,B)

如果数据中存在NaN值,执行逻辑运算会报错
如果数据中存在复数,执行逻辑运算也会报错

  • &&和||
    &&和||只能对标量(只有一个值)进行逻辑运算 ,不能对有多个元素的向量或者矩阵进行运算,而&和|可以。比如我们上面那个练习题,你只能使用&和|进行运算。
    &&和||进行逻辑运算时具有短路功能 ,可以提高运行效率:
    计算A && B时,如果A为逻辑0,则B不会被判断,因为最后的结果一定是逻辑0;计算A || B时,如果A为逻辑1,则B不会被判断,因为最后的结果一定是逻辑1。

4.2 利用逻辑值对矩阵进行索引

有一个m行n列的矩阵A,我们要提取其指定位置的元素,那么我们可以生成一个和A同样大小的逻辑矩阵L,L中的元素要么是逻辑值1,要么是逻辑值0,其中:等于逻辑值1的元素所处的位置是我们所需要的。接着我们只需要使用命令A(L)

必须要用逻辑值

matlab 复制代码
A = 1:20  % 这20名同学的编号为1,2,......,20
x = randi([0,1],1,20)  % 随机生成一组由0和1构成的随机数
L = logical(x)  % 转换成逻辑值
A(L)

命令A(L)得到的结果是一个列向量,在MATLAB中,矩阵的数据在计算机的内存中被存储为单列,由矩阵的各列顺次连接而成

L必须是逻辑矩阵,即里面的0和1都必须是逻辑值,不能是由数字0和1构成的数值矩阵。如果L是数值矩阵,可以使用logical函数进行转换

4.3 缺失值的识别和填补

10 NaN 5 2 NaN 8 5\],其中第二个元素和第五个元素为NaN 将A中所有的NaN值替换成所有非缺失值的平均值

matlab 复制代码
A(isnan(A)) = mean(A(~isnan(A)))

4.4 all、any 和 find 函数

all函数相当于对向量或者矩阵的元素进行'逻辑与&'运算,只有全为非零值时才返回逻辑值1。而any函数则相当于对元素进行'逻辑或|'运算,存在至少一个非零值时就会返回逻辑值1

判断整个矩阵的元素是否全部为非零值

matlab 复制代码
A = randi([0,2],2,2)
all(A(:))
all(all(A))
  • find
matlab 复制代码
A = [4 0 11 -3 0 2 -4];
ind = find(A)
[r, c] = find(A)
A = [0 -1 0 0;
     4 0 0 3;
     0 1 0 0];
ind = find(A, 2)
ind = find(A, 2, 'last')
[row,col] = find(A)
[row,col,v] = find(A)

五、运算符优先级

养成好的习惯:使用小括号来指定计算的先后顺序! 这样会清晰很多


六、集合运算

6.1 unique

unique函数可用来提取数组中的唯一值,它可以用在我们学过的向量和矩阵 上,也可以用在我们未来章节要学的表格上。
C = unique(A) 会对向量A进行去重操作,C中的每一个元素都来自向量A且互不相同,同时,MATLAB会自动将C进行排序。

**返回值:**这里的ia和ic都是索引向量:

  • ia是C中的每个元素在A中的索引值
  • ic是A中的每个元素在C中的索引值
    因此有下面的等式成立:A(ia)等于C 且 C(ic)等于A
matlab 复制代码
A = [5 -6 5 10 8 -6 -3 -3]
[C,ia,ic] = unique(A)

也可以指定一个输入参数'stable',这样会按照与A中相同的顺序返回C中的值。

matlab 复制代码
A = [5 -6 5 10 8 -6 -3 -3];
C = unique(A,'stable')
A = [5 -6 5 10 8 -6 -3 -3];
[C,ind] = unique(A,'stable')

unique还可以作用到矩阵上,如果A是一个矩阵,那么unique(A)的结果和unique(A(:))的结果相同。

matlab 复制代码
A = [3     5
    6     8
    3     5
    4     1
    2     8
    2     5
    4     1]
C = unique(A)   % 等价于unique(A(:))

当A为矩阵,也有A(ia)等于C 且 C(ic)等于A

matlab 复制代码
A
[C,id1,id2] = unique(A)  % 返回的索引是线性索引

如果我们加一个输入参数'rows',那么unique(A, 'rows')会将A的每一行视为一个整体,会返回A中的唯一行。

matlab 复制代码
A
[C,id1,id2] = unique(A,'rows')  % 返回的索引是行索引

6.2 ismember

h = ismember(A,B)可以判断数组A中的元素是否在数组B内,h是和A同等大小的逻辑数组,为逻辑1时说明该位置的A元素在B中存在,为逻辑0时说明在B中不存在。

matlab 复制代码
A = [4 1 3 4 8];
B = [3 7 4 5 4 9 6];
h = ismember(A,B)
A = [3,1;
     8,5;
     4,0];
B = [3 7 4 5 4 9 6];
h = ismember(A,B)
A = [3,1;
     8,5;
     4,0];
B = [3 7 4 5;
     1 4 9 6];
h = ismember(A,B)

ismember可以有两个返回值:[h, ib] = ismember(A,B)

h就是上面的那个逻辑数组。

ib是和A大小相同的一个数组,对于 A 中属于 B 的成员的每一个值,ib 会包含该值在 B 中的最小索引;如果值为 0 表示 A 不是 B 的成员。

matlab 复制代码
A = [4 1 3 4 8];
B = [3 7 5 4 9 6];
[h, ib] = ismember(A,B)

另外,如果B和A的列数相同,那么我们可以加一个输入参数'rows',这时候ismember(A, B, 'rows')会将A的每一行视为一个整体,然后在B中查找。

matlab 复制代码
A = [6 8;
    3 5;
    4 1];
B = [1 2
    3 5
    3 8
    6 1];
[h, ib] = ismember(A,B,'rows')

6.3 模拟中彩票

已知某彩票由三个数组成(有顺序),每个数都是1-10上的整数

如果玩家买的三个数字和开奖号码的三个数字完全相同(包括顺序),则中了一等奖;

如果有任意两个数字相同(包括顺序),则中了二等奖。

其他情况则都不算中奖。

例如开奖号码是5 3 7,玩家号码是5 6 7、4 3 7都中了二等奖;3 5 7 则不中奖,因为顺序不同。

现在请你模拟以下情形:

某玩家买了100张彩票,彩票票面数字都是随机生成的。

已知今天的开奖号码是8,3,5,请判断是否中了一等奖和二等奖,若中了请返回中奖的彩票数字和对应的索引。

matlab 复制代码
x = randi([1,10],100,3)   %  随机生成100张彩票
y = [1 2 3];  % 中奖的彩票

判断一等奖

matlab 复制代码
ydj = ismember(x,y,'rows');
ind1 = find(ydj)
x(ind1,:)

二等奖

matlab 复制代码
edj1 =  ismember(x(:,[1,2]),y([1,2]),'rows') & (x(:,3) ~= y(3));
edj2 =  ismember(x(:,[2,3]),y([2,3]),'rows') & (x(:,1) ~= y(1));
edj3 =  ismember(x(:,[1,3]),y([1,3]),'rows') & (x(:,2) ~= y(2));
ind2 = find(edj1 | edj2 | edj3)
x(ind2,:)

还有一种更简单的方法:

matlab 复制代码
x = randi([1,10],100,3)
y = [1 2 3]; 
x(sum(x == y,2) == 2,:)

思考:如果不要求顺序相同,只要求数字相同就能中奖,代码应该怎么改?

例如:开奖号码是5 3 7,玩家号码是3 5 7、3 7 5都能中一等奖;4 7 5、7 7 3都能中二等奖

一等奖(要排序)

matlab 复制代码
x = randi([1,10],100,3)   %  随机生成100张彩票
y = [5 3 7];  % 中奖的彩票
x_copy = x;
x = sort(x,2)
y = sort(y)

二等奖

matlab 复制代码
edj1 =  ismember(x(:,[1,2]),y([1,2]),'rows') & (x(:,3) ~= y(3));
edj2 =  ismember(x(:,[2,3]),y([2,3]),'rows') & (x(:,1) ~= y(1));
edj3 =  ismember(x(:,[1,3]),y([1,3]),'rows') & (x(:,2) ~= y(2));
edj4 =  ismember(x(:,[1,2]),y([1,3]),'rows') & (x(:,3) ~= y(2));
edj5 =  ismember(x(:,[2,3]),y([1,2]),'rows') & (x(:,1) ~= y(3));
edj6 =  ismember(x(:,[1,3]),y([2,3]),'rows') & (x(:,2) ~= y(1));
edj7 =  ismember(x(:,[1,2]),y([2,3]),'rows') & (x(:,3) ~= y(1));
edj8 =  ismember(x(:,[2,3]),y([1,3]),'rows') & (x(:,1) ~= y(2));
edj9 =  ismember(x(:,[1,3]),y([1,2]),'rows') & (x(:,2) ~= y(3));
ind2 = find(edj1 | edj2 | edj3 | edj4 | edj5 | edj6 | edj7 | edj8 | edj9)
x(ind2,:)

6.4 intersect、union、setdiff和setxor函数

这四个函数分别用于计算两个数组之间的交集、并集、差集和对称差集,下面给出了这四个函数对应的维恩图。

C = intersect(A,B)会返回数组A和B的共同数据,但是不包含重复项,返回的C默认会排序

matlab 复制代码
A = [5 3 1 4 2 7 2];
B = [2 8 6 1 0 3 9 5];
C = intersect(A,B)
A = [1 2 4;
    3 4 8];
B = [1 3;
    8 7;
    1 2];
C = intersect(A,B) 

还可以增加一个输入参数'stable',这样会按照在A中出现的顺序返回C中的值。

matlab 复制代码
A = [5 3 1 4 2 7 2];
B = [2 8 6 1 0 3 9 5];
C = intersect(A,B,'stable')

A和B的列数相同,那么我们可以加一个输入参数'rows',这时候intersect (A, B, 'rows')会将A和B的每一行视为一个整体,然后找到公共的行。

matlab 复制代码
A = [3 3 3;
     0 0 1; 
     1 0 3; 
     1 1 1];
B = [1 0 3; 
     3 3 3; 
     0 0 0];
C = intersect(A,B,'rows')

intersect函数可以有最多三个返回值

C,ia,ib\] = intersect(___) 还使用上述任何语法返回索引向量 ia 和 ib。 一般情况下,C = A(ia) 且 C = B(ib)。 如果指定了 'rows' 选项,则 C = A(ia,:) 且 C = B(ib,:)。 ```cpp A = [5 3 1 4 2 7 2]; B = [2 8 6 1 0 3 9 5]; [C,ia,ib] = intersect(A,B) A = [5 3 1 4 2 7 2]; B = [2 8 6 1 0 3 9 5]; [C,ia,ib] = intersect(A,B,'stable') A = [3 3 3; 0 0 1; 1 0 3; 1 1 1]; B = [1 0 3; 3 3 3; 0 0 0]; [C,ia,ib] = intersect(A,B,'rows') ``` 剩余三个函数的用法intersect类似 ### 6.5 线性代数相关的函数 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/81e8fff053394bc584c88ce7a63206ba.png) * det 计算方阵的行列式 ```matlab A = [6 2 1; 10 10 8; 4 3 3]; det(A) ``` * rank 计算矩阵的秩 ```matlab A = [9 8 8 5; 7 4 2 6; 7 4 2 6]; rank(A) ``` * trace 计算方阵的迹(对角线元素的和) ```matlab A = [4 6 5; 1 3 3; 6 7 6]; trace(A) ``` rref 将矩阵化简成行最简型矩阵 ```matlab A = [2 4 4 1; 6 10 8 7; 1 8 9 1]; rref(A) ``` inv 计算方阵的逆矩阵,inv(X)的结果和X\^(-1)相同 ```matlab A = [2 3 4; 3 2 5; 3 7 8]; inv(A) ``` transpose 返回转置矩阵(有复数的话转置后虚部符号保持不变),transpose(A)和A.'的结果相同 ```matlab A = [1 2; 3 8; 1 4]; transpose(A) ``` * **triu与tril** ```matlab A = [9 6 8 6 2 9 1 2 4 0 7 2 5 1 4 6 8 6 5 2 9 5 1 2 1]; triu(A) triu(A,1) triu(A,-1) tril(A) ``` * **eig** eig函数可用来计算方阵的特征值和特征向量,它有两种最基础的用法: **e = eig(A) 返回一个列向量,e中包含方阵A的所有特征值。** **\[V,D\] = eig(A) 返回特征向量构成的矩阵V和特征值构成的对角矩阵D,V中的每一列就是D中对应特征值的特征向量。** 应用:请你将上方A矩阵的特征值从大到小降序排列,对应的特征向量的顺序也要跟着特征值的顺序改变。 ```matlab e = diag(D) % 取出特征值 [sort_e, ind] = sort(e, 'descend') % 将特征值降序排列 D_new = diag(sort_e) V_new = V(:, ind) ``` * **norm** norm函数: 用来计算向量或者矩阵的范数 p-范数等价于:`sum(abs(x).^p) ^ (1/p) % 这里的1/p要加括号` 1-范数和2-范数都属于p-范数的特例,MATLAB中**p默认取2** ,即`norm(x)`表示计算2-范数 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/711c98123df94eec827ab38a1f332591.png) 求空间上两点的距离 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/663a874094334ddba0b892e6698ddc2a.png) ```matlab norm(x-y) % sum((x-y).^2) ^ (1/2) ``` ## 文章结语 感谢你读到这里~我是「**键盘敲碎了雾霭**」,愿这篇文字帮你敲开了技术里的小迷雾 💻 如果内容对你有一点点帮助,不妨给个暖心三连吧👇 👍 **点赞** \| ❤️ **收藏** \| ⭐ **关注** (听说三连的小伙伴,代码一次编译过,bug绕着走~) 你的支持,就是我继续敲碎技术雾霭的最大动力 🚀 🐶 小彩蛋: /^ ^\ / 0 0 \ V\ Y /V / - \ / | V__) || 摸一摸毛茸茸的小狗,赶走所有疲惫和bug~我们下篇见 ✨

相关推荐
九皇叔叔2 小时前
MySQL实操指南:复制表及数据复制全解析
android·数据库·mysql
今日说"法"2 小时前
线性代数与矩阵运算:AI世界的数学基石——从SVD到特征值分解的实战解析
人工智能·线性代数·矩阵
猴哥聊项目管理2 小时前
从职能型组织到矩阵型组织的IPD转型路径
线性代数·矩阵·项目管理·项目经理·ipd流程·ipd项目管理流程·ipd流程管理
梦想不只是梦与想2 小时前
flutter 与 Android iOS 通信?以及实现原理(一)
android·flutter·ios·methodchannel·eventchannel·basicmessage
清 晨3 小时前
海外社媒内容审核加强跨境卖家如何避免限流
大数据·人工智能·矩阵·新媒体运营·内容营销
Evand J3 小时前
【雷达跟踪代码介绍】基于matlab卡尔曼滤波器雷达多目标跟踪(双雷达 多目标 分布式融合)
分布式·matlab·目标跟踪·多目标跟踪·雷达跟踪
Lambert_lin03 小时前
Android grade9.0 之后 自定义apk 名称
android·kotlin
fengci.4 小时前
ctfshow其他(web408-web432)
android·开发语言·前端·学习·php
南宫萧幕4 小时前
储能系统SOC管理三要素:高精度OCV标定、校正器设计工具、SOC均衡下垂控制
matlab·控制