用运算符 >、== 这样的,满足条件的位置为逻辑 1,不满足条件的位置为逻辑 0
以 is 开头的函数,可以进行一些类型的判断,比如isnan,判断每个元素是否为 nan
符号 | 含义 |
---|---|
& | 与 |
| | 或 |
~ | 非 |
xor(A, B) | 异或 |
all(A) | 是否全为非0 |
any(A) | 是否有0 |
与运算在 if 里面是 && 而在逻辑数组运算的时候是 & ,或运算也一样。
A = [1, 2, 3; 4, 5, 6];
B = A(A > 3);
C = A .* (A > 3);
D = A .* A > 3;
加点是对每个元素操作,不加点是对矩阵进行操作
B 是一个列向量,里面包含了大于 3 的所有值
C 是一个数组,里面小于等于 3 的值全部被置为 0
D 的运算顺序是先 .* 后 > 所以结果是逻辑数组
A = [1, 2, 3; 4, 5, 6; 7, 8, 9];
B = [1 0 1];
C = A(B == 1, :);
D = A(:, B == 1);
以上的代码是经常碰到的情况,A 是一个 m * n 的矩阵,B 是一个向量,现在要根据 B 条件筛选 A
可以看到,用切片的形式写逻辑向量,就会根据 B == 1 所代表的逻辑 1 筛选行和列。
无论 B 是行向量或是列向量都不影响,因为在切片里面,都化为了一维索引。
产生 0~1 随机数,size 指定产生矩阵的维度。
rand(3,4) 产生 3 × 4 的随机矩阵
产生标准正态分布随机数,size 指定矩阵维度。
产生 imin 和 imax 之间的整数,包含 imin 和 imax
如果省略 imin 则生成 0 到 imax 之间整数
randi(5,2,3) 则产生 1 到 5 的之间的随机数,生成一个 2 × 3 矩阵
产生一个行向量,其中包含在 1 到 n(包括二者)之间随机选择的 k 个唯一整数,其顺序也是随机的。
若省略 k ,则返回行向量,其中包含从 1 到 n(包括二者)之间的整数随机置换。
函数 | 说明 |
---|---|
M=mean(A) | 计算矩阵A平均值 |
M=mean(A, dim) | 计算指定维度上向量的平均值 |
nanmean | 算术平均值 |
geomean | 几何平均值 |
harmmean | 和谐平均值 |
trimmean | 调整平均值 |
函数 | 说明 |
---|---|
V=var(X) | 计算方差(n-1标准化) |
V=var(X,1) | 计算二阶中心距(n标准化) |
V=var(X,w) | w为权重向量 |
V=var(X,w,dim) | dim规定计算的维度 |
std | 计算上述对应的算术平均值 |
方差和二阶中心距:
S^2 = \frac{1}{n-1} \sum_{i=1}^n (X_i- \bar{X})^2 \quad \quad
\tilde{S}^2 = \frac{1}{n} \sum_{i=1}^n (X_i- \bar{X})^2
函数 | 说明 |
---|---|
cov(x) | x为向量时计算方差,x为矩阵时计算协方差矩阵 |
cov(x,y) | 计算x、y的协方差矩阵 |
cov(x,1) | 使用n标准化 |
cov(x,y,1) | 使用n标准化 |
函数 | 说明 |
---|---|
R=corrcoef(X) | 计算矩阵X列向量元素相关系数矩阵 |
R=corrcoef(x,y) | 计算列向量x、y的相关系数矩阵 |
[R,P]=corrcoef(...) | P返回的是不相关的概率矩阵 |
[R,P,PLO,PUR]=corrcoef(...) | RLO、RUP是95%置信度的估计区间上、下限 |
函数 | 随机数名 |
---|---|
unifrnd | 连续均匀分布 |
unidrnd | 离散均匀分布 |
exprnd | 指数分布 |
normrnd | 正态分布 |
chi2rnd | 卡方分布 |
trnd | t分布 |
Frnd | F分布 |
gamrnd | γ分布 |
betarnd | β分布 |
lognrnd | 对数正态分布 |
nbinrnd | 负二项式分布 |
ncfrnd | 非中心 F 分布 |
nctrnd | 非中心 t 分布 |
ncx2rnd | 非中心卡方分布 |
raylrnd | 瑞利分布 |
weibrnd | 韦伯分布 |
binornd | 二项分布 |
geornd | 几何分布 |
hygernd | 超几何分布 |
poissrnd | 泊松分布 |
参数表前面是各分布的参数,后面的m、n是产生随机数的行列数
n = 10:10:60
% 求六个随机数,每个随机数参数由 n 向量决定
r1 = binornd(n, 1./n)
% 产生两行四列的随机数,随机数参数是10和0.1
r2 = binornd(10, 1/10, [2,4])
name取值1 | name取值2 | 分布 |
---|---|---|
beta | Beta | β |
bino | Binomial | 二项 |
chi2 | Chisquare | 卡方 |
exp | Exponential | 指数 |
f | F | F |
gam | Gamma | γ |
geo | Geometric | 几何 |
hyge | Hypergeometric | 超几何 |
logn | Lognormal | 对数正态 |
nbin | Negative Binomial | 负二项式 |
ncf | Noncentral F | 非中心F |
nct | Noncentral t | 非中心t |
ncx2 | Noncentral Chi-square | 非中心卡方 |
norm | Normal | 正态 |
poiss | Poisson | 泊松 |
rayl | Rayleigh | 瑞利 |
t | T | t |
unif | Uniform | 均匀 |
unid | Discrete Uniform | 离散均匀 |
weib | Weibull | 韦伯 |
其中 X 表示数据点,A表示分布的参数
上述特殊分布的概率密度可以同等价的函数,如F分布可以用 fpdf( )
任意函数的概率密度可用函数 ksdensity
% 表示在 x = 6 处,分布参数为 7,8 的概率密度
y = pdf('F',6, 7, 8)
% 计算 x = 5 和 x = 6 的概率密度
y = pdf('F', [5 6], 7, 8)
% 计算参数为 7,8 和 9,10 的概率密度
y = pdf('F', 6, [7, 9], [8, 10])
y = fpdf(6, 7, 8)
将概率密度计算的函数 pdf 改为 cdf 即计算累积概率值。
sort(A,dim)
对 A 中元素按一定顺序进行排列,默认 dim = 1,对每一列排序。
注意 sort 会对每一列的数据进行排序,会破坏同一行之间的对应关系
[B,I] = sort(A,dim)
返回的 B 为对应排序后的矩阵,返回的矩阵 I 的第 i 行表示排序后的第 i 行是原矩阵 A 的第 I(i) 行。
要对矩阵 A 根据第一列排序,应用如下代码进行:
A = [1 5 6;5 9 4;3 5 7;6 8 2];
[B,I] = sort(A(:,1));
C = zeros(4,3);
for i = 1:4
C(i,:) = A(I(i),:);
end
disp(A);
disp(C);
k = find(X,n)
返回矩阵 X 中前 n 个非零元素的索引
若省去 n 则返回所有非零元素索引
若要查询等于 a 的位置,可以用 X == a 表示,同样查询小于 a 的位置可以用 X < a 表示
[row, col] = find(X,n)
返回矩阵 X 中满足要求的横坐标和纵坐标
如果仅仅要得到矩阵中满足要求的元素,可以用以下的逻辑形式改善性能
clear
A = [1 5 6;5 9 4;3 5 7;6 8 2];
L = A <= 4
B = A(A <= 4)
C = A.*(A <= 4)
gscatter(x,y,g,color,marker,size)
以 x 为x轴,y 为y轴,根据 g 的对应分类情况作散点图
g 必须和 x、y相同维度,可以是数字表示,也可以是分类变量
color 表示颜色,marker 是符号,size 是大小
load discrim
gscatter(ratings(:,1),ratings(:,2),group,'br','xo')
xlabel('climate')
ylabel('housing')
将 x 轴刻度选择 angle 角度。
当 x 轴数据长度过长时,会出现重叠情况,将其旋转一定角度可以避免重叠
将 x 轴刻度按规定显示
在神经网络等算法中,需要划分数据为三份:train(训练数据)、validate(验证数据)、test(测试数据),本函数可以方便随机划分为三类
Q 是正整数,是样本总数量
后三个参数是三类所占百分比,在 0~1 之间,默认值为0.7, 0.15, 0.15
得到的是三组数据的序号行向量。
## assignin(ws,var,val)
ws 有两种情况,‘base’ 或 ‘caller’,其中 ‘base’ 表示基础工作区,‘caller’ 在函数嵌套中使用,主函数调用子函数,‘caller’表示主函数区。
ws 为 ‘base’ 时,表示将 val 赋值给基础工作区的变量 var。
assignin('base','name',n);
不会为数组的特定元素赋值,下面的代码会出错。
assignin('base','X(3:5)',-1); % 错误
执行 expression,它是一个字符向量或字符串标量,包含任何有效的 MATLAB 表达式,这些表达式使用工作区 ws 中的变量。
可以用这个函数将基础工作区的变量赋值到局部函数区
v = evalin('base', 'var');
将变量 var 赋给 v
拿到的数据是 table 的形式,我们需要知道一些基本的方法,把 table 转换为我们熟悉的数组。
tableName.Properties.VariableNames
tableName为表的名称,返回一个 Cell,Cell 中为表中每个属性的名称。
tableName.PropertyName
PropertyName 为表中某个属性名称,如果这个属性是数字,则返回一个数组,否则返回元胞数组。
table2array(tableName)
返回一个数组,里面包含表中的数字数据。
varfun(func,T)
对表 T 中每一个元素进行 func 例如:
varfun(@double,T):化为小数
varfun(@mean,T):求均值
varfun(func,T,Name,Value)
设置一组属性值,如 ‘OutputFormat’ 指定输出格式。
tabulate(T)
统计信息
构造函数
T = table(var1,...,varN)
根据变量名 var 构造表,所有变量的行数必须相同
T = table('Size',sz,'VariableTypes',varTypes)
为表格创建空间,sz 为行向量,指定维数,例如【4,3】表示 4 行 3 列;varTypes为数据类型元胞数组。
sz = [4 3]; varTypes = {'double','datetime','string'}; T = table('Size',sz,'VariableTypes',varTypes)
- ##### T = table(___,'VariableNames',varNames)
- 指定输出表中的变量的名称,即每一列的名称;第四种添加每一行的名称。
- ##### T = table(___,'RowNames',rowNames)
```matlab
T = table(categorical({'M';'F';'M'}),[45;32;34],logical([1;0;0]),... 'VariableNames',{'Gender','Age','Vote'},... 'RowNames',{'NY';'CA';'MA'})
- ##### T = table
- 建立空 table 对象
## 通过转换构建表
- 可以通过 array2table、cell2table、struct2table 等构造表
- 区分table与array2table
```matlab
a = [1 2 3;4 5 6]
A = table(a)
B = array2table(a)
struct2table用法
S.Name = {'CLARK';'BROWN';'MARTIN'};
S.Gender = {'M';'F';'M'};
S.SystolicBP = [124;122;130];
S.DiastolicBP = [93;80;92];
struct2table(S)
使用 Dot + VariableNames 可以返回指定名称的列,返回的是一个 Cell 数组
可以和数组一样使用 ()访问,返回的依旧是 table,如果是 {} 则返回 Cell 数组
删除行列
T(3,:) = [];
添加行列
T.name1 = {'var1';'var2';'var3'};
合并table
t1 = [1 2 3;4 5 6]
table(t1)
t2 = [7 8 9;3 5 7]
table(t2)
T1 = [t1;t2]
T2 = [t1,t2]
如果是;连接两个表格,则是行数变多,列数不变
如果是,连接两个表格,则是行数不变,列数增多
对table进行排序
sortrows函数
筛选和查找
利用逻辑运算筛选
T1 = T(T.name1 > 200,:);
T2 = T( (T.name2 > 200) & (T.name3 > 200),: );
T3 = T(strcmp(T.name4,'name'),:);
要求文件名与函数名相同
function [a, b] = functionName(c, d)
end
输出一个
eg:在名为average.m的文件中定义一个函数,该函数接受输入向量,计算值的平均值,并返回单个结果
function ave = average(x)
ave = sum(x(:))/numel(x);
end
z = 1:99;
ave = average(z)
输出:
输出多个
eg:在名为stat.m的文件中定义一个函数,该函数返回输入向量的平均值和标准偏差。
function [m,s] = stat(x)
n = length(x);
m = sum(x)/n;
s = sqrt(sum((x-m).^2/n));
end
%从命令行调用函数
values = [12.7, 45.4, 98.9, 26.6, 53.1];
[ave,stdev] = stat(values)
输出:
一个文件中多个函数
定义一个函数,将输入限制为不包含Inf或NaN元素的数字向量。此函数使用arguments关键字
function [m,s] = stat3(x)
arguments
x (1,:) {mustBeNumeric, mustBeFinite}
end
n = length(x);
m = avg(x,n);
s = sqrt(sum((x-m).^2/n));
end
function m = avg(x,n)
m = sum(x)/n;
end
用@引用函数后可以间接使用函数
h = @cos;
h(pi);
这里 h(pi)就相当于 cos(pi),因为 h 引用了 cos 函数的句柄。
更常见的情况是将引用的句柄当做函数的参数传入另一个函数(主函数),这样在主函数中,我们就可以根据输入调用不同的函数。例如:
% main.m
function test(functionHandle)
a = functionHandle(pi/4);
disp(a)
end
% 命令行
test(@sin);
test(@tan);
会输出 0.71 和 1
可以用 @ 构造简单的匿名函数,例如:
h = @(x) x^2 + sin(x);
这样其实相当于建立了一个函数文件,将其句柄赋给了 h,但是并没有真实存在的 m 文件,而是直接用 h 表示了。
将其理解成一个函数 m 文件,就很好理解 h 可以直接计算函数值,例如 h(4);但是并不能进行符号运算,例如 h + h 就会报错。
这是属于 MATLAB 符号运算的知识,各种符号函数的区别,移步符号函数。
在 MATLAB 中,函数重载不能像 C++ 一样通过不同的参数类型进行重载,而要在函数体内实现。
简单的说就是 “伪重载”,用 if 判断,当输入为什么时怎么样。
函数体内有几个系统自动设定的变量,帮助我们完成重载。
nargin 为调用函数时输入的参数个数
在 MATLAB 中,不需要定义时的参数与调用时的参数个数相同,即定义参数(x,y)但是调用时可以只输入参数 x
特别注意在类的方法中,obj 参数虽然在调用时并不用写,但是也算一个参数(这是面向对象的知识,小白可以无视)
输入的参数可以只用一个 varargin 表示,然后调用时输入的参数都在这个 varargin 元胞数组中,用 varargin{1} 即可获得第一个输入参数
注意在类的方法中,如果用 对象名.方法名(参数) 调用,varargin 第一个参数是这个对象而不是我们输入的第一个参数。
classdef Point2D < handle
properties
x;
y;
end
methods
function obj = Point2D(x0,y0)
obj.x = x0;
obj.y = y0;
end
function moveTo(varargin)
disp(varargin)
disp(varargin{1})
end
end
end
varargin 可以出现在已有参数的末尾,例如上面这个例子,在类的方法中我们肯定会用到 obj 这个参数,所以我们可以将其单独拿出来。
function moveTo(obj,varargin)
if nargin == 1
obj.x = 0;
obj.y = 0;
elseif nargin == 2
obj.x = varargin{1};
obj.y = 0;
elseif nargin == 3
obj.x = varargin{1};
obj.y = varargin{2};
end
disp(nargin)
disp(varargin)
end
同理,nargout 表示输出的参数个数,varargout 表示输出,用于重载输出。
% 逗号或空格表示同一行的数,分号表示不同行
A = [1, 2, 3; 4 5 6];
% 分号表示 起始:间距:终值
A = 1:3; %[1 2 3]
A = 1:2:5; %[1 3 5]
% linspace函数,参数分别为起始值、中值、取点数量。等距离取点,得到等差数组
A = linspace(0, pi, 100);
除了上述常用方法,还有下面的特殊函数:
命令 | 说明 | 命令 | 说明 |
---|---|---|---|
eye(n) | n×n单位阵 | eye(m,n) | m×n单位阵 |
ones(n) | n×n全1矩阵 | ones(m,n) | m×n全1矩阵 |
zeros(n) | n×n全0矩阵 | zeros(m,n) | m×n全0矩阵 |
rand(n) | n×n随机矩阵 | rand(m,n) | m×n随机矩阵 |
diag(v) | v为对角元素创建方阵 | diag(v,k) | v为第k条对角线创建矩阵 |
% 第 1 行第 2 列
A(1, 2)
% 第 2 行所有列
A(2, :)
% 倒数第二行,第 1、3、5列
A(end-1, [1 3 5])
对切片进行复制可以修改,但是两边矩阵的大小要一模一样。
A([2, 4, 6], [1, 3]) = [8, 6; 5, 7; 5, 4];
直接对切片赋 [],即可删除。
以下总结了常用的矩阵相关函数,简单来说,所有你能想到的基本操作都有对应的函数,想干什么直接 google 以下,找都函数名就行了。
命令 | 说明 |
---|---|
rot90(A) | 将A逆时针旋转90° |
rot90(A,k) | 将A逆时针旋转k×90° |
flipdim(X,dim) | dim=1时上下翻转,dim=2时左右翻转 |
det(A) | 求矩阵行列式 |
eig(A) | 求矩阵特征值 |
inv(A) | 求矩阵的逆 |
rank(A) | 求矩阵的秩 |
trace(A) | 求矩阵的迹 |
A = [1, 2, 3; 4, 5, 6];
% 每个元素都加 1
B = A + 1
% 对应元素分别相加
B = A + [7, 8, 9; 10, 11, 12];
% 第一行加 1,第二行加 2
B = A + [1; 2];
%第一列加 1,第二列加 2,第三列加 3
B = A + [1, 2, 3];
矩阵的乘法,就要注意了, * ^ / \ 对应的是矩阵的乘除运算,在前面加一个 . 才表示对应位置的数据分别相乘、相除。
A/B 表示 ,A\B 表示 ,而 A./B 和 A.\B 就没区别了。
A = [1, 2; 3, 4];
B = [3, 4; 5, 6];
% 矩阵乘法
C = A * B;
% 对应位置相乘
C = A .* B;
一个向量可以代表一个多项式,例如 [3 -2 1 0 5] 可以对应多项式:
3x^4-2x^3+x^2+5
所以可以直接用向量调用下面的函数就可以进行多项式运算:
求p1和p2对应多项式的乘积。
k返回的是多项式p除以q的商,r是余式。即
求对应多项式导数的向量。
将多项式函数化为向量。其中 f 是数学符号表达式。
本文章使用limfx的vscode插件快速发布