Matlab技巧

实用技巧

计算欧几里得举例:vecnorm、pdist

计算欧式距离别再傻憨憨地去背两点之间的距离公式了,直接一个二范数就搞定了。

比如,A=[1 1;2 2;3 3]为三行两列的矩阵,行表示点,列表是 X X X Y Y Y 坐标,同理,B=[5 5;6 6;7 7]

那么计算A和B三点对应的欧氏距离,可以直接用vecnorm(A-B,2,2)

vecnormnorm都是计算范数的函数,但是vecnorm可以指出对行或列上的范数(默认是对列计算)。

第二个参数是要计算的范数类型,第三个参数是对行计算,对列计算是 1 1 1,对行计算为 2 2 2

pdist 函数可以计算各种距离。

重复数组:repmat

重复数组不要去用循环什么的,直接repmat函数就好了。

比如,把A矩阵横向重复三次,repmat(A,1,3)。把 A \mathbf{A} A矩阵纵向重复两次,repmat(A,2,1)

注意,这里虽然也有横向和纵向的区分,但是并不是想上面的例子中那样,纵向用1表示,横向用2表示。而是在第二和第三个参数来指出每个维度上的重复次数。当然,也可以是三维,四维等等。

当然repmat(A,2,2)可以理解为把矩阵A看做一个单元,扩充为[A, A; A, A]

随机选取整数:randperm,randi

这两个函数都是随机选取整数,randperm是无放回的选取,randi是有放回的选取。

比如,要从1-10之间选出3个不重复的整数,可以用randperm(10,3)。而不加上第二个参数,就是1-10之间的整数随机排列。

如果要从1-10之间选出3个整数,可以重复,可以用randi(10,1,3),这样生成的就是1行3列的3个整数。还可以写成randi([1,10],1,3)这样的形式来指出选取的范围。

归一化处理:mapminmax

对数据的归一化处理公式如下,其中, x ˉ \bar{x} xˉ为均值。
y i = x i − x m i n x m a x − x m i n y_i=\frac{x_i-x_{min}}{x_{max}-x_{min}} yi=xmaxxminxixmin

虽然计算不难,但是对矩阵的每一行进行归一化,就还是比较麻烦。可以采用mapminmax函数。注意,mapminmax是对每一行进行归一化。

比如,对矩阵 X 每一行进行归一化,Y=mapminmax(X,0,1)。得到的 Y 是处于 0-1 之间的归一化。函数默认的是 -1到1的归一化

判断数组中是否出现某个元素:ismember

这个函数应该是比较常见的函数,但是这里想要想要记录下是因为参数位置不同,返回的结果也是不一样的。

比如, a a a为一个标量, B \mathbf{B} B为一个向量,如果 B \mathbf{B} B中含有 a a a,即Lia=ismember(B,a),则得到的Lia为一个向量,只有数值为 a a a的位置才等于1,其余的为0。

而要表示 a a a是否被包含在 B \mathbf{B} B中,可以写作Lia=ismember(a,B),这样得到的就是0或者是1了。

总结一下,就是函数ismember返回的结果与第一个参数的大小相同。

分贝与功率的转化:db2pow,pow2db,db

在计算分贝值的时候,很多时候会遇到功率值与分贝之间的换算。换算并不难,但是写多了就很麻烦(主要是懒得记。。。)。分贝换算公式如下:
X ( d B ) = 10 log ⁡ 10 ( X ) X(dB)=10\log_{10}(X) X(dB)=10log10(X)
这里再写上 d B dB dB d B m dBm dBm的换算
P ( d B ) = 10 log ⁡ 10 ( P ( W ) 1000 ) P(dB)=10\log_{10}(\frac{P(W)}{1000}) P(dB)=10log10(1000P(W))

为了简单,可以采用x=pow2db(x)计算分贝,这里要注意,如果计算功率的 d B m dBm dBm形式,变量x要换成毫瓦。同理,将功率计算为毫瓦的形式,可以用x=db2pow(x)

当然也可以用x=db(x,"power"),这个函数是将能量或功率测量值转换为分贝,可以通过制定第二个参数来实现功率与分贝之间的转换。

范数的泰勒级数展开:taylor

在做连续凸近似的时候往往会需要对范数进行一阶泰勒展开,当然可以选择手写求偏导,但是很容易出现错误。这里先给出泰勒展开式的公式。
一元函数 f ( x ) f(x) f(x) 在点 x 0 x_0 x0 处的泰勒展开如下:
f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + O ( x − x 0 ) ≈ f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) \begin{array}{ll} f(x)&=f(x_0)+f'(x_0)(x-x_0)+O(x-x_0)\\ &\approx f(x_0)+f'(x_0)(x-x_0) \end{array} f(x)=f(x0)+f(x0)(xx0)+O(xx0)f(x0)+f(x0)(xx0)
二元函数 f ( x , y ) f(x,y) f(x,y) 在点 ( x 0 , y 0 ) (x_0,y_0) (x0,y0) 处的泰勒展开如下:
f ( x , y ) ≥ f ( x 0 , y 0 ) + ( ∂ f ∂ x + ∂ f ∂ y ) f ( x 0 , y 0 ) + ⋯ + 1 n ! ( ∂ f ∂ x + ∂ f ∂ y ) n f ( x 0 , y 0 ) f(x,y)\geq f(x_0,y_0)+(\frac{\partial f}{\partial x}+\frac{\partial f}{\partial y})f(x_0,y_0)+\cdots+\frac{1}{n!}(\frac{\partial f}{\partial x}+\frac{\partial f}{\partial y})^nf(x_0,y_0) f(x,y)f(x0,y0)+(xf+yf)f(x0,y0)++n!1(xf+yf)nf(x0,y0)
但是当你在对 norm(x-y) 直接用 taylor 展开时,Matlab会报错,告诉你无法使用泰勒级数。这是因为,函数泰勒级数存在的条件之一是该函数应该是无限可微的。而 x − y x-y xy 会在 0 0 0 处产生从 − 1 -1 1 0 0 0 1 1 1 的阶跃。因此是不满足可微的条件。

不过可以在求泰勒级数之前,加上 x > y x>y x>y 的条件。

assume(x>y)

补充一点:
当在调用 norm(x-y) 函数时,Matlab会将其写作 (abs(x-y)^2)^(1/2)。因此在对其求导之后得到一个 sign(x-y) 的符号函数。

获取矩阵无重复行:unique

获取无重复项,或者判断矩阵内是否包含重复项也是挺常见的操作。有时候操作的时候,会要求整行进行比对。比如判断坐标矩阵 A N × 2 A^{N\times 2} AN×2中是否有重复的坐标。这个时候需要将考虑x坐标和y坐标是否都相同。当然可以通过写循环来逐一判断。但是这样不仅容易出错,也很麻烦。这时候就可以用unique(·)函数。

unique(·)函数可以返回无重复项,但是对整行操作时,需要加上参数'rows',即unique(A,'rows')

unique(·)函数默认是对数组进行排序的,如果不想排序想按照原来的顺序,可以再加上参数'stable',即unique(A,'rows','stable')

对两个数组应用按元素运算 bsxfun

这个是我现在新学的一个技巧,我觉得很实用。对于两个维度不一样的矩阵对点操作,需要类似于Python中的广播的操作。之前的写法,往往是通过repmat的方法,将两个矩阵的大小补齐。这种方法虽然快但是占内存。当然也可以选择不占内存的方式,for循环即可,这种方式虽然不占内存但是耗时。于是就有了介于两者之间的bsxfun,隐式扩展。

函数形式为C = bsxfun(@fun,A,B),其中,@fun时函数句柄(不了解句柄的自行百度以下,自己写得匿名函数,不需要加@),AB为矩阵,注意,这里要求两个矩阵中必须有一个某一个维度上是1。这也很好理解,比如 A N × 1 A^{N\times 1} AN×1 B N × 3 B^{N\times 3} BN×3进行首先会将A在第二维度上repmat上3,然后再对点相乘。如果 A N × 2 A^{N\times 2} AN×2这就不好算了,至少更复杂了。

支持bsxfun的句柄函数除了自己写得匿名函数,还有一些函数。

函数符号说明函数符号说明
plus+eq==等于
minus-ne~=不等于
times.*对点乘gt>大于
rdivide./对点右除ge>=大于等于
ldivide.\对点左除lt<小于
power.*+对点幂le<=小于等于
and&按元素逻辑 ANDor|按元素逻辑 OR

计算数组元素个数 numel

Matlab想要计算数组的长度一般有这么几种方式(x = [[1 2 3];[3 4 5]]举例):

  • 计算数组最大维度的长度:lengthlength(x)=3
  • 计算数组的大小:sizesize(x)=[2 3]
  • 计算数组元素的个数:numelnumel(x)=6,其实就相当于prod(size(x)),也就是每个维度大小的乘积。

【不推荐,了解即可】初始化空数组,x = []

在Python中,最常用的就是列表的初始化,直接x = []就可以了,其实matlab也可以这样做,甚至更好用,比如

>> x = []
x = []
>> x(1, :) = [1 2] 
x =
     1     2
>> x(3, :) = [3 4]
x =
     1     2
     0     0
     3     4

可以看出matlab没有数组长度范围的限制,可以中间隔几行赋值。但是不推荐采用这种方法,因为矩阵没有预分配,运行速度会变慢。

  • 4
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值