我想每个人都会同意MATLAB语言不是很漂亮,或者特别是一致。但是没关系!我们仍然必须使用它来完成工作。
您最喜欢的使事情变得轻松的窍门是什么?让我们为每个答案提供一个答案,以便人们在同意的情况下可以将其投票。另外,尝试通过示例来说明您的答案。
Answers:
使用内置的探查器来查看我的代码的热门部分在哪里:
profile on
% some lines of code
profile off
profile viewer
或仅使用内置tic
和toc
获取快速计时:
tic;
% some lines of code
toc;
使用逻辑数组直接提取满足特定条件的矩阵元素:
x = rand(1,50) .* 100;
xpart = x( x > 20 & x < 35);
现在,xpart仅包含位于指定范围内的那些x元素。
通过在帮助注释中添加“另请参阅”行,可以快速访问其他功能文档。首先,必须在所有大写字母中包含函数名称作为第一行注释。进行通常的注释标头工作,然后另请以逗号分隔其他相关功能列表。
function y = transmog(x)
%TRANSMOG Transmogrifies a matrix X using reverse orthogonal eigenvectors
%
% Usage:
% y = transmog(x)
%
% SEE ALSO
% UNTRANSMOG, TRANSMOG2
在命令行上键入“ help transmog”时,您将在此注释标题中看到所有注释,并带有指向列出的其他功能的注释标题的超链接。
使用单个冒号将矩阵转换为向量。
x = rand(4,4);
x(:)
myElems = [1:10 21:30 31:40...181:190]; y = x(myElems);
sub2ind
会有所帮助
匿名函数,原因如下:
quad
和fminbnd
以函数作为参数的函数。在脚本(不以函数头开头的.m文件)中,它也很方便,因为与真实函数不同,您不能包含子函数。。
% quick functions
f = @(x) 3*x.^2 + 2*x + 7;
t = (0:0.001:1);
plot(t,f(t),t,f(2*t),t,f(3*t));
% closures (linfunc below is a function that returns a function,
% and the outer functions arguments are held for the lifetime
% of the returned function.
linfunc = @(m,b) @(x) m*x+b;
C2F = linfunc(9/5, 32);
F2C = linfunc(5/9, -32*5/9);
图形中公式的LaTeX模式:在最新版本(R2006?)之一中,您,'Interpreter','latex'
在函数调用的末尾添加了其他参数,它将使用LaTeX渲染。这是一个例子:
t=(0:0.001:1);
plot(t,sin(2*pi*[t ; t+0.25]));
xlabel('t');
ylabel('$\hat{y}_k=sin 2\pi (t+{k \over 4})$','Interpreter','latex');
legend({'$\hat{y}_0$','$\hat{y}_1$'},'Interpreter','latex');
不知道他们何时添加它,但是它可以在text(),title(),xlabel(),ylabel(),zlabel()甚至legend()函数中与R2006b一起使用。只要确保您使用的语法没有歧义即可(因此,对于legend(),您需要将字符串指定为单元格数组)。
plot
命令的向量长度不同,因此Matlab将对您的示例抛出错误。我想您正在尝试绘制两条线,对吧?您需要在传递给plot命令的矩阵中使用分号,以使Matlab知道这是两个单独的系列,即像这样:plot(t,sin(2*pi*[t ; t+0.25]));
这是一个简单的例子:
我发现用逗号分隔的列表语法对于构建函数调用非常有用:
% Build a list of args, like so:
args = {'a', 1, 'b', 2};
% Then expand this into arguments:
output = func(args{:})
[one two three four] = {1 2 3 4}{:}
我有很多原因喜欢使用函数句柄。首先,它们是我在MATLAB中找到的最接近指针的东西,因此您可以为对象创建类似引用的行为。您也可以使用它们进行一些简单(简单)的操作。例如,替换switch语句:
switch number,
case 1,
outargs = fcn1(inargs);
case 2,
outargs = fcn2(inargs);
...
end
%
%can be turned into
%
fcnArray = {@fcn1, @fcn2, ...};
outargs = fcnArray{number}(inargs);
我只是认为这样的小事很酷。
使用nargin设置可选参数的默认值,并使用nargout设置可选输出参数。快速示例
function hLine=myplot(x,y,plotColor,markerType)
% set defaults for optional paramters
if nargin<4, markerType='none'; end
if nargin<3, plotColor='k'; end
hL = plot(x,y,'linetype','-', ...
'color',plotColor, ...
'marker',markerType, ...
'markerFaceColor',plotColor,'markerEdgeColor',plotColor);
% return handle of plot object if required
if nargout>0, hLine = hL; end
if exist('plotColor', 'var') ...
,因为那样您就使用了参数的名称,而不仅仅是参数的编号。
哦,反转数组
v = 1:10;
v_reverse = v(length(v):-1:1);
flipud()
或fliplr()
做这件事。但是,与步骤结合使用,这将更加有用。例如v(end:-4:1)。
使用聚合函数(例如最小值,最大值,均值,差异,和,任意,全部,...)时,请严格指定尺寸
例如,该行:
reldiff = diff(a) ./ a(1:end-1)
计算向量中元素的相对差异可能会很好,但是如果向量退化为一个元素,则计算将失败:
>> a=rand(1,7);
>> diff(a) ./ a(1:end-1)
ans =
-0.5822 -0.9935 224.2015 0.2708 -0.3328 0.0458
>> a=1;
>> diff(a) ./ a(1:end-1)
??? Error using ==> rdivide
Matrix dimensions must agree.
如果为函数指定了正确的尺寸,则此行将返回一个空的1×0矩阵,这是正确的:
>> diff(a, [], 2) ./ a(1, 1:end-1)
ans =
Empty matrix: 1-by-0
>>
min函数通常在矩阵的各列上计算最小值,直到矩阵仅包含一行为止。-然后,它将返回该行中的最小值,除非Dimension参数另有说明,可能会破坏您的应用程序。
我几乎可以保证您,因此设置这些聚合函数的尺寸将为您节省以后的大量调试工作。
至少对我来说就是这种情况。:)
a(1:end)
的,而不是a(1:end-1)
diff
大小为n的向量上应用的结果为大小为n-1。
用于操作数组的冒号运算符。
@ ScottieT812,提到了一个:展平数组,但是还有其他所有选择数组位的变体:
x=rand(10,10);
flattened=x(:);
Acolumn=x(:,10);
Arow=x(10,:);
y=rand(100);
firstSix=y(1:6);
lastSix=y(end-5:end);
alternate=y(1:2:end);
使用ismember()合并由文本标识符组织的数据。当您分析不同的条目(以公司符号为例)来回走动时,很有用。
%Merge B into A based on Text identifiers
UniverseA = {'A','B','C','D'};
UniverseB = {'A','C','D'};
DataA = [20 40 60 80];
DataB = [30 50 70];
MergeData = NaN(length(UniverseA),2);
MergeData(:,1) = DataA;
[tf, loc] = ismember(UniverseA, UniverseB);
MergeData(tf,2) = DataB(loc(tf));
MergeData =
20 30
40 NaN
60 50
80 70
使用sim
命令直接从脚本(而不是以交互方式)执行Simulink模型。您可以执行一些操作,例如从工作空间变量中获取参数,然后重复运行sim
在循环中以模拟某些事物,同时更改参数以查看行为如何变化,并使用所需的任何图形命令绘制结果的图形。比尝试以交互方式进行操作要容易得多,并且在可视化结果时,它比Simulink“示波器”模块为您提供了更大的灵活性。(尽管您不能使用它来实时查看模拟运行中的情况)
要知道的一个非常重要的事情是命令的DstWorkspace
和SrcWorkspace
选项simset
。这些控件控制“到工作区”和“来自工作区”块的获取和放置结果的位置。Dstworkspace
默认为当前的工作空间(例如,如果你调用sim
从一个函数里面的“到工作区”块将显示为变量来自同一功能中访问),但SrcWorkspace
默认为基工作区,如果你想你的电话封装了sim
你会想要设置SrcWorkspace
为,current
以便有一个干净的界面来提供/获取模拟输入参数和输出。例如:
function Y=run_my_sim(t,input1,params)
% runs "my_sim.mdl"
% with a From Workspace block referencing I1 as an input signal
% and parameters referenced as fields of the "params" structure
% and output retrieved from a To Workspace block with name O1.
opt = simset('SrcWorkspace','current','DstWorkspace','current');
I1 = struct('time',t,'signals',struct('values',input1,'dimensions',1));
Y = struct;
Y.t = sim('my_sim',t,opt);
Y.output1 = O1.signals.values;
向量化:
function iNeedle = findClosest(hay,needle)
%FINDCLOSEST find the indicies of the closest elements in an array.
% Given two vectors [A,B], findClosest will find the indicies of the values
% in vector A closest to the values in vector B.
[hay iOrgHay] = sort(hay(:)'); %#ok must have row vector
% Use histogram to find indices of elements in hay closest to elements in
% needle. The bins are centered on values in hay, with the edges on the
% midpoint between elements.
[iNeedle iNeedle] = histc(needle,[-inf hay+[diff(hay)/2 inf]]); %#ok
% Reversing the sorting.
iNeedle = iOrgHay(iNeedle);
使用 persistent
运行在线算法时(静态)变量。它可以加快贝叶斯机器学习等领域的代码速度,在该领域中,针对新样本迭代地训练模型。例如,对于计算独立对数似然,我首先从头计算对数似然,然后通过将先前计算的对数似然与其他对数似然相加来对其进行更新。
除了给出更专业的机器学习问题外,我还提供了一个通用的在线平均代码,该代码是我从这里获取的:
function av = runningAverage(x)
% The number of values entered so far - declared persistent.
persistent n;
% The sum of values entered so far - declared persistent.
persistent sumOfX;
if x == 'reset' % Initialise the persistent variables.
n = 0;
sumOfX = 0;
av = 0;
else % A data value has been added.
n = n + 1;
sumOfX = sumOfX + x;
av = sumOfX / n; % Update the running average.
end
然后,通话将产生以下结果
runningAverage('reset')
ans = 0
>> runningAverage(5)
ans = 5
>> runningAverage(10)
ans = 7.5000
>> runningAverage(3)
ans = 6
>> runningAverage('reset')
ans = 0
>> runningAverage(8)
ans = 8
persistent
这很危险,因为您不能直接设置内部状态,这意味着您无法正确测试。同样,这意味着您一次只能在一个地方使用该功能。例如,如果要计算两个独立数量的运行平均值,则需要复制文件以分隔状态。
令我惊讶的是,尽管人们提到了索引数组的逻辑数组方法,却没人提到find命令。
例如,如果x是NxMxO数组
x(x> 20)的工作方式是生成一个NxMxO逻辑数组并将其用于对x进行索引(如果您有大型数组并且正在寻找小的子集,则可能会很糟糕
x(find(x> 20))的工作方式是生成满足x> 20的x索引列表(即1xwhatever),并以此索引x。根据我的经验,应该多使用“查找”。
我称之为“技巧”的更多内容
如果您不知道所需的大小,则可以使用end + 1来增长/追加到数组和单元格数组(只要切片的尺寸匹配,也可以使用较大的尺寸,所以也可以使用/)在这种情况下,必须将x初始化为[]以外的其他值)。不适用于数字,但适用于事物(或单元格数组)的小型动态列表,例如,解析文件。
例如
>> x = [1,2,3] x = 1 2 3 >> x(end + 1)= 4 x = 1 2 3 4
另一个认为很多人不知道的是,对于在任何昏暗的1数组上的作品,因此继续该示例
>>对于n = x; disp(n);结束 1个 2 3 4
这意味着,如果您只需要x的成员,则无需为它们建立索引。
这也适用于单元格数组,但是有点令人讨厌,因为在遍历它们时,元素仍然包裹在单元格中:
>> for el = {1,2,3,4}; disp(el); end [1] [2] [3] [4]
因此,要获取元素,您必须将其下标
>> for el = {1,2,3,4}; disp(el {1}); end 1个 2 3 4
我不记得有没有更好的办法。
find
在这种情况下使用它是一个坏主意,因为它是多余的且速度较慢。我个人认为逻辑方法更清晰,因为它也避免了其他混乱情况。
-您可以创建Matlab快捷方式到名为startup.m的初始化文件。在这里,我定义了Matlab会话的格式,输出精度和绘图参数(例如,我使用了较大的绘图轴/字体大小,以便在演示文稿中可以清晰地看到.fig。)一位开发人员关于此的博客文章http://blogs.mathworks.com/loren/2009/03/03/whats-in-your-startupm/。
-您可以使用“加载”功能加载整个数字ascii文件。这不是特别快,但是可以快速完成原型制作工作(那不是Matlab的座右铭吗?)
-如前所述,冒号运算符和向量化是救生员。螺丝环。
x = repmat([1:10],3,1); %说,x是数据的示例数组
l = x> = 3; %l是逻辑向量(1s / 0s),用于突出显示数组中满足特定条件的那些元素。
N = sum(sum(l));%N是满足该给定条件的元素数。
欢呼声-祝脚本编写愉快!
N = sum(I(:));
任何维度。
numel(x>=3)