가장 좋아하는 MATLAB / Octave 프로그래밍 트릭은 무엇입니까?
저는 모든 사람들이 MATLAB 언어가 예쁘지 않거나 특히 일관성이 없다는 데 동의 할 것이라고 생각합니다. 신경 쓰지 마! 우리는 여전히 그것을 사용하여 일을 처리해야합니다.
일을 더 쉽게하기 위해 가장 좋아하는 트릭은 무엇입니까? 사람들이 동의하면 투표 할 수 있도록 답변마다 하나씩 만들어 봅시다. 또한 예를 들어 답을 설명하십시오.
내장 된 프로파일 러를 사용하여 내 코드의 주요 부분을 확인합니다.
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의 요소 만 포함합니다.
도움말 주석에 "SEE ALSO"행을 추가하여 다른 기능 문서에 빠르게 액세스 할 수 있습니다. 먼저 첫 번째 주석 줄로 모두 대문자로 된 함수 이름을 포함해야합니다. 일반적인 주석 헤더 작업을 수행 한 다음 다른 관련 기능의 쉼표로 구분 된 목록과 함께 SEE ALSO를 입력하십시오.
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(:)
루프 벡터화 . 이를 수행하는 방법에는 여러 가지가 있으며 코드에서 루프를 찾고 벡터화 할 수있는 방법을 확인하는 것은 재미 있습니다. 벡터 연산으로 성능이 놀랍도록 빨라졌습니다!
몇 가지 이유로 익명 함수 :
- 3x ^ 2 + 2x + 7과 같이 일회성 사용을위한 빠른 기능을 만듭니다. (아래 목록 참조) 이는 함수를 인수로 취하는
quad
및 같은 함수에 유용합니다fminbnd
. 실제 함수와 달리 하위 함수를 포함 할 수 없기 때문에 스크립트 (함수 헤더로 시작하지 않는 .m 파일)에서도 편리합니다. - 에 대한 폐쇄 - 익명 함수가 있지만 조금의 mutate 상태로 그 안에 할당을 할 수있는 방법이있을 것 같지 않습니다으로 제한.
.
% 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);
Matlab의 bsxfun , arrayfun , cellfun , structfun 은 매우 흥미롭고 종종 루프를 저장합니다.
M = rand(1000, 1000);
v = rand(1000, 1);
c = bsxfun(@plus, M, v);
예를 들어이 코드는 행렬 M의 각 열에 열 벡터 v를 추가합니다.
하지만 애플리케이션의 성능이 중요한 부분에서는 루프가 여전히 더 빠르기 때문에 이러한 함수를 사소한 for 루프와 비교하여 벤치마킹해야합니다.
그래프의 공식을위한 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 ()에서는 문자열을 셀형 배열로 지정해야합니다).
xlim 및 ylim을 사용하여 수직선과 수평선을 그립니다. 예 :
y = 10에 수평선을 그립니다.
line(xlim, [10 10])
x = 5에 수직선 그리기 :
line([5 5], ylim)
다음은 간단한 예입니다.
쉼표로 구분 된 목록 구문은 함수 호출을 작성하는 데 매우 유용합니다.
% Build a list of args, like so:
args = {'a', 1, 'b', 2};
% Then expand this into arguments:
output = func(args{:})
다음은 수시로 유용한 여러 가지 명확하지 않은 함수입니다.
mfilename
(현재 실행중인 MATLAB 스크립트의 이름을 반환)dbstack
(matlab 함수 스택의 이름 및 줄 번호에 액세스 할 수 있습니다)keyboard
(실행을 중지하고 디버깅 프롬프트에 대한 제어를 양보합니다. 이것이 디버그 프롬프트에 K가있는 이유입니다.K>>
dbstop error
(자동으로 오류를 유발하는 라인에서 중지 된 디버그 모드로 전환)
여러 가지 이유로 함수 핸들을 사용하는 것을 좋아합니다. 우선, 그것들은 내가 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
Matlab에서 Java 코드 호출
자동화 된 for 루프를위한 cellfun 및 arrayfun.
아, 그리고 배열 반전
v = 1:10;
v_reverse = v(length(v):-1:1);
할당의 왼쪽에있는 조건부 인수 :
t = (0:0.005:10)';
x = sin(2*pi*t);
x(x>0.5 & t<5) = 0.5;
% This limits all values of x to a maximum of 0.5, where t<5
plot(t,x);
축 속성을 알아라 ! 원하는 작업을 수행하기 위해 기본 플로팅 속성을 조정하기 위해 설정할 수있는 모든 종류가 있습니다.
set(gca,'fontsize',8,'linestyleorder','-','linewidth',0.3,'xtick',1:2:9);
(예를 들어, 글꼴 크기를 8pt로, 모든 새 선의 선 스타일을 모두 단색으로, 너비를 0.3pt로, xtick 포인트를 [1 3 5 7 9]로 설정)
선 및 그림 속성도 유용하지만 축 속성을 가장 많이 사용합니다.
min, max, mean, diff, sum, any, all, ...과 같은 집계 함수를 사용할 때 차원을 지정하는 데 엄격해야합니다.
예를 들어 라인 :
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.
함수에 올바른 차원을 지정하면이 행은 올바른 빈 1x0 행렬을 반환합니다.
>> diff(a, [], 2) ./ a(1, 1:end-1)
ans =
Empty matrix: 1-by-0
>>
행렬이 하나의 행으로 만 구성 될 때까지 일반적으로 행렬의 열에 대해 최소값을 계산하는 최소 함수도 마찬가지입니다. -그러면 차원 매개 변수가 달리 명시하지 않는 한 행에 대해 최소값을 반환하고 응용 프로그램을 중단 할 수 있습니다.
결과적으로 이러한 집계 함수의 차원을 설정하면 나중에 디버깅 작업을 상당히 줄일 수 있음을 거의 보장 할 수 있습니다.
적어도 저에게는 그랬을 것입니다. :)
배열 조작을위한 콜론 연산자.
@ 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);
함수를 빠르게 테스트 할 수 nargin
있도록 다음과 같이 사용합니다 .
function result = multiply(a, b)
if nargin == 0 %no inputs provided, run using defaults for a and b
clc;
disp('RUNNING IN TEST MODE')
a = 1;
b = 2;
end
result = a*b;
나중에 다른 입력 조건에 대해 함수를 테스트하기 위해 단위 테스트 스크립트를 추가합니다.
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
'이유'묻기 (Matlab 런타임 실패 디버깅 트랜스에서 오전 3시를 방해하는 데 유용합니다 ...)
sim
명령을 사용하여 대화식이 아닌 스크립트에서 직접 Simulink 모델을 실행합니다 . 작업 공간 변수에서 매개 변수를 가져오고 반복적 sim
으로 루프에서 실행 하여 매개 변수를 변경하면서 동작이 어떻게 변경되는지 확인하고 원하는 그래픽 명령으로 결과를 그래프로 표시하는 등의 작업을 수행 할 수 있습니다. 이 작업을 대화식으로 수행하는 것보다 훨씬 쉽고 결과를 시각화 할 때 Simulink "오실로스코프"블록보다 훨씬 더 많은 유연성을 제공합니다. (시뮬레이션이 실행되는 동안 실시간으로 무슨 일이 일어나고 있는지 확인하는 데 사용할 수는 없지만)
A really important thing to know is the DstWorkspace
and SrcWorkspace
options of the simset
command. These control where the "To Workspace" and "From Workspace" blocks get and put their results. Dstworkspace
defaults to the current workspace (e.g. if you call sim
from inside a function the "To Workspace" blocks will show up as variables accessible from within that same function) but SrcWorkspace
defaults to the base workspace and if you want to encapsulate your call to sim
you'll want to set SrcWorkspace
to current
so there is a clean interface to providing/retrieving simulation input parameters and outputs. For example:
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;
Contour plots with [c,h]=contour
and clabel(c,h,'fontsize',fontsize)
. I usually use the fontsize
parameter to reduce the font size so the numbers don't run into each other. This is great for viewing the value of 2-D functions without having to muck around with 3D graphs.
Vectorization:
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);
Using persistent
(static) variables when running an online algorithm. It may speed up the code in areas like Bayesian machine learning where the model is trained iteratively for the new samples. For example, for computing the independent loglikelihoods, I compute the loglikelihood initially from scratch and update it by summing this previously computed loglikelihood and the additional loglikelihood.
Instead of giving a more specialized machine learning problem, let me give a general online averaging code which I took from here:
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
Then, the calls will give the following results
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
I'm surprised that while people mentioned the logical array approach of indexing an array, nobody mentioned the find command.
e.g. if x is an NxMxO array
x(x>20) works by generating an NxMxO logical array and using it to index x (which can be bad if you have large arrays and are looking for a small subset
x(find(x>20)) works by generating list (i.e. 1xwhatever) of indices of x that satisfy x>20, and indexing x by it. "find" should be used more than it is, in my experience.
More what I would call 'tricks'
you can grow/append to arrays and cell arrays if you don't know the size you'll need, by using end + 1 (works with higher dimensions too, so long as the dimensions of the slice match -- so you'll have to initialize x to something other than [] in that case). Not good for numerics but for small dynamic lists of things (or cell arrays), e.g. parsing files.
e.g.
>> x=[1,2,3] x = 1 2 3 >> x(end+1)=4 x = 1 2 3 4
Another think many people don't know is that for works on any dim 1 array, so to continue the example
>> for n = x;disp(n);end 1 2 3 4
Which means if all you need is the members of x you don't need to index them.
This also works with cell arrays but it's a bit annoying because as it walks them the element is still wrapped in a cell:
>> for el = {1,2,3,4};disp(el);end [1] [2] [3] [4]
So to get at the elements you have to subscript them
>> for el = {1,2,3,4};disp(el{1});end 1 2 3 4
I can't remember if there is a nicer way around that.
-You can make a Matlab shortcut to an initialization file called startup.m. Here, I define formatting, precision of the output, and plot parameters for my Matlab session (for example, I use a larger plot axis/font size so that .fig's can be seen plainly when I put them in presentations.) See a good blog post from one of the developers about it http://blogs.mathworks.com/loren/2009/03/03/whats-in-your-startupm/ .
-You can load an entire numerical ascii file using the "load" function. This isn't particularly fast, but gets the job done quickly for prototyping (shouldn't that be the Matlab motto?)
-As mentioned, the colon operator and vectorization are lifesavers. Screw loops.
x=repmat([1:10],3,1); % say, x is an example array of data
l=x>=3; % l is a logical vector (1s/0s) to highlight those elements in the array that would meet a certain condition.
N=sum(sum(l));% N is the number of elements that meet that given condition.
cheers -- happy scripting!
참고URL : https://stackoverflow.com/questions/132092/what-is-your-favourite-matlab-octave-programming-trick
'development' 카테고리의 다른 글
NSDate를 사용하여 요일 가져 오기 (0) | 2020.10.22 |
---|---|
iOS 8 앱에서 상태 표시 줄 숨기기 (0) | 2020.10.22 |
DateTime.ToString ()을 사용할 때 요일 접미사 얻기 (0) | 2020.10.22 |
Mac OS Sierra 10.12에 Nokogiri를 설치하는 방법 (0) | 2020.10.22 |
FrameLayout의 Android 센터보기가 작동하지 않습니다. (0) | 2020.10.22 |