随机类
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
三维矢量图: