matlab常用函数

随机类

randperm

作用:随机生成一系列有序的数参看

p = randperm(6)
p = randperm(10, 3) % 从0~10中产生3个数,且各不一样 


附perms-全排列

排列组合-nchoosek

参看:https://blog.csdn.net/yangziluomu/article/details/50215443

n = [1 4 2 7 8 3 9 5 6];  % 元素可以重复
k = 3; res = nchoosek(n, k); % n是一个向量,从n中选k个元素 

结果如下(部分截图):

以一定概率产生随机数

randsrc(m,n,[alphabet; prob])
% m和n表示生成的随机数矩阵的行数和列数
% alphabet表示需要产生的随机数的数字,用一个行向量表示
% prob表示这些数字出现的概率大小,用一个行向量表示,向量长度和alphabet向量要完全相同, 且这些概率的和要为1
% 比如:要产生1、4、 6这三个数。它们分别出现的概率为 0.1、0.2、0.7,如何设计程序使得按照这个概率产生10个随机数呢?
alphabet = [1 4 6]; prob = [0.1 0.2 0.7];
randsrc(10,1,[alphabet; prob])

获取一个向量元素在另一个向量种的索引

ismember函数

ismember只能获取首个,不能获取所有的

x = [2 1 4 3];
y = [3 7 3 8 9 1 2 3 7 5 ];
[is pos] = ismember(x, y); 

结果如下:因为y种没有4,所以第三个索引为0

需求在此,参看:https://www.ilovematlab.cn/thread-469661-1-1.html

a = [6 4 12 12 6 7 2 3 1 6 9 12 15 15];  % a和b的维度可以不一致
b = [7 12 14 13 2 8 3 4 6 9 10 15 5 11];  % b中的元素也可以重复
[ia,ib]=find(bsxfun(@eq,a,b')); w=accumarray(ib,1:numel(ib),[],@(x){ia(x)}); celldisp(w) % w是一个元组,维度同a,即w{ia}代表a的第i个元素在b中的索引(可以为多个) 

结果如下:

求向量或矩阵的累计和/积向量

累计和:cumsum(X)

累计积:cumprod(X)

参看:https://blog.csdn.net/qq_32515081/article/details/81053959

效果:

怎么找到一个向量中的元素与另一个向量中那个元素最近?

参看:https://www.ilovematlab.cn/thread-472649-1-1.html

方法一:

A = [0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0]; B = [0, 1, 2.1, 3.1, 4.0]; D = abs(bsxfun(@minus, A.', B));
M = min(D, [], 1); [Index, ~] = find(bsxfun(@eq, M, D));
Near = A(Index);
% 上述代码没有利用排序信息,做了很多不必要的计算。 % 使用循环,如二分法查找,则可以利用排序信息。 

方法二:

A = [0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0];
B = [0, 1, 2.1, 3.1, 4.0];
B_len=length(B);
Near=zeros(1,B_len);
Index=zeros(1,B_len);
j1=0;
for i=1:B_len   
	data=A-B(i);
	[value,id]=min(abs(data));
	id_min=find(abs(data)==value);
	id_min_len=length(id_min);
	j2=j1+id_min_len;
	Near(j1+1:j2)=A(id_min);
	Index(j1+1:j2)=id_min;
	j1=j2;
end 

找到连续n个1(logicMatrix)

m = [1,0,0,1,1,1,1,0,1,1,1,0,0,0,1];
% [0, m, 0] = [0, 1,0,0,1,1,1,1,0,1,1,1,0,0,0,1, 0];
% diff[0, m, 0] = [1,-1,0,1,0,0,0,-1,1,0,0,-1,0,0,1,-1];
k = find(diff([0,m,0]))';  % 前后补零、前向差分、找到非0元素索引
% 偶数位置-奇数位置。g的元素个数就代表了有几次连续的1
g = find(k(2:2:end)- k(1:2:end)>=3);  % 连续3个1及以上
[k(2*g-1),k(2*g)-1];


解读:第一次连续3个1以上是4-7、第二次是9~11

一般化

在一个向量中寻找n个连续的m

1.根据要求化为逻辑向量:X = (X == m)

X = [1 0 0 0 1 1 1 1 0 1 0];  % 逻辑化后

2.根据第一步,值为m的现在都为1,即现在就是找连续的n个1
3.X前后都补零,然后使用diff进行一阶前向差分:X = diff(X, 1)。

X = [0 1 0 0 0 1 1 1 1 0 1 0 0];  % 前后补零
X = [1,-1,0,0,1,0,0,0,-1,1,-1,0];  % 一阶前向差分后,且第一个非零元素为1

4.经过第3步后,X中非零元素的顺序必定是1和-1交替、且第一个是1,即1、-1、1、-1、......
1代表1的开始、-1代表1的结束
5.找到X中非零元素的索引:index = find(X)

index = [1,2,5,9,10,11];  % 非零元素的索引,且第一个为1
% 即X(index(2:2:end))都为-1、X(index(1:2:end))都为1,1和-1交替
% 而连续的n个1,其一阶前向差分后必定是1 0 0 ... 0 0 -1,
% 比如原本是 0 1 1 1 0 1、补零后 0 0 1 1 1 0 1 0
% 一阶前向差分后 0 1 0 0 -1 1 -1
% 有两段 1到-1的变化,1代表1的开始、-1代表1的结束
% 非零偶数位置(-1) - 非零奇数位置(1):[5 7] - [2 6] = [3 1]

6.取index中偶数位置元素pos1 = index(2:2:end);取奇数位置元素pos2 = index(1:2:end)。
7.num = find((pos1 - pos2) >= n);
在一个逻辑向量X中找连续n个0,则在X的前后补1,然后一阶前向差分。得到的结果中除去零元素后只有-1和1,且第一个必定是-1。
在一个逻辑向量X中找连续n个1,则在X的前后补0,然后一阶前向差分。得到的结果中除去零元素后只有-1和1,且第一个必定是1。

matlab中的数据游标

一个图像中,选择工具-数据游标,这样就可以选中图中的点,并且显示出其对应的坐标。如果想继续选其它点,按住shift或alt后再点击。
1.点中某个数据游标,可以按键盘上的上下左右键微调
2.左击数据游标,点击“编辑文本更新函数”,然后对其中的代码进行更改。


然后保存,然后左击点击“选择文本更新函数”,选择刚才保存的文件,然后再选择数据点使,游标特别大。

matlab中画矢量图-quiver

碰到这个函数是因为在做2020年时的亚太杯时在网上找了求离散点的曲率时碰到的,网上有现成的代码(已下载至E盘文件夹中)

链接
实际例子
函数参数的理解

% quiver 二维的
quiver(x, y, u, v);
% x, y, u, v的维度一样,(x, y)表示点,(u, v)表示(x, y)的方向,其长度为sqrt(u^2+v^2)
% 但是在图中不一定会体现出模的长度,即可能是等比例缩小的。
x = [2 3 1];
y = [1 7 9];
u = [1 8 2];
v = [2 -3 5];
quiver(x, y, u, v);
% quiver-3 三维
x = [2 3 1];
y = [1 7 9];
z = [2 3 -2];
u = [1 8 2];
v = [2 -3 5];
w = [-7 3 2];
quiver3(x, y, z, u, v, w);

% 
[x,y] = meshgrid(-2:.2:2,-1:.15:1);
z = x .* exp(-x.^2 - y.^2);
[u,v,w] = surfnorm(x,y,z);
quiver3(x,y,z,u,v,w); hold on, surf(x,y,z), hold off

三维矢量图:

赞赏