在MATLAB中打高尔夫球的技巧


Answers:


10

开始打高尔夫球之前必须知道的一些事情:

在MATLAB计算中,字符的行为与其ASCII代码相同。

'abc' - 'a'  % Returns: [0 1 2]
'123' - '0'  % Returns: [1 2 3]
'“' == 8220  % Returns: 1 (logical)
'a':'e'==100 % Returns: [0 0 0 1 0] (logical)

9

缩短属性名称

在MATLAB中,可以缩短字符串识别属性,只要它不会导致歧义即可。

plot(X,'C','k') % Ambiguous property found.
plot(X,'Co','k') % Expands to Color  (black)

这实际上赢得了我一个挑战:)


2
很好,尽管答案是正确的,但我想强调一下,这适用于对的名称,name, value如上所示。(所以不要这样sort(rand(4,1),'descend')
Dennis Jaheruddin

1
它确实也适用于其中的某些事物,例如,conv(1:5,[1 1],'s')代替conv(1:5,[1 1],'same')
Luis Mendo

6

可以通过与char串联来将其转换为char:

x='a'+magic(5) % Array with character codes of several letters

char(x) % The standard way
['' x] % The compact way

尽管它只保存一个字符,但可以经常使用。



4

通过离散傅立叶变换的统一根

给定一个正整数n,生成第- n个单位的标准方法是

exp(2j*pi*(0:n-1)/n)

这使根开始于1正角方向并沿正角方向移动。如果顺序无关紧要,可以将其缩短为

exp(2j*pi*(1:n)/n)

由于exp(2j*pi/4)等于虚数单位(j),因此可以写得更紧凑,如下所示(由于@flawr而引起的技巧):

j.^(4*(0:n-1)/n)

要么

j.^(4*(1:n)/n)

但是离散傅立叶变换提供了更短的方法(感谢@flawr删除了两个不必要的括号):

fft(1:n==n)

它使根开始于1正角方向并在正角方向上移动;要么

fft(1:n==2)

它开始于1负角方向并向负角方向移动。


这里尝试上述所有方法。


大把戏!您甚至可以打高尔夫球fft(1:n==2)
更加瑕疵的

@flawr我从不知道优先规则...谢谢!
路易斯·门多

3

nnz 有时可以为您节省几个字节:

  • 假设您想要一个逻辑矩阵的总和A。代替sum(sum(A))sum(A(:)),您可以使用nnz(a)nnz暗含(:))。
  • 如果您想知道数组中元素的数量,并且可以确保没有零,则numel(x)可以使用nnz(x)。例如,如果x是字符串,则适用。

3

矩阵中向量的迭代。

给定一组向量作为矩阵,您实际上可以通过单个for循环对它们进行迭代,例如

for v=M
    disp(v);
end

而“传统上”您可能会这样做

for k=1:n
    disp(M(:,k));
end

我刚刚从@Suever那里了解了这个挑战中的技巧。


3

Octave相关但不完全相同的技巧

MATLAB和Octave的一个鲜为人知且很少使用的功能是,大多数内置函数都可以在不带括号的情况下调用,在这种情况下,它们会将其后的任何内容都视为字符串(只要它不包含空格)。如果包含空格,则需要引号。使用以下命令时,通常可以节省一个字节disp

disp('Hello, World!')
disp 'Hello, World!'

其他不太有用的示例包括:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12

实际上,我在“您能数多少?”中使用了两次。-挑战:

strchr sssssssssssssst t

等价strchr('sssssssssssssst','t')并返回15

nnz nnnnnnnnnnnnnn

等价nnz('nnnnnnnnnnnnnn')并返回14

东西也像gt r s作品(相当于'r'>'s'或)gt('r','s')


2

内置的oneszeros是空间通常是浪费。您可以通过简单地将(所需大小的)数组/矩阵乘以0(以获得的输出)来获得相同的结果。zeros),并以1如果您想要输出ones

d = rand(5,2);

%// Using zeros
z = zeros(size(d));

%// Not using zeros
z = d*0;

%// Using ones
o = ones(size(d));

%// Not using ones
o = 1+d*0

如果要创建零或一维矩阵大小的列或行向量,这也可以使用。

p = rand(5,2);

z = zeros(size(p,1), 1);
z = 0*p(:,1);

o = ones(size(p, 1), 1);
o = 1+0*p(:,1);

如果要创建特定大小的矩阵,可以使用,zeros但也可以将最后一个元素分配为0,然后让MATLAB填充其余的元素。

%// This
z = zeros(2,3);

%// vs. This
z(2,3) = 0;

2
我喜欢~(1:n)用于一维零向量。
sintax

2

2D卷积核

这可能是一个小众话题,但显然有些人喜欢在这里对各种事物使用卷积。[需要引用]

在2D中,通常需要以下内核:

0 1 0
1 1 1
0 1 0

这可以通过使用

v=[1,2,1];v'*v>1 %logical
v=[1,0,1];1-v'*v  %as numbers

短于

[0,1,0;1,1,1;0,1,0]

经常使用的另一个内核是

0 1 0
1 0 1
0 1 0

可以使用缩短

v=[1,-1,1];v'*v<0   % logical
[0,1,0;1,0,1;0,1,0] % naive verison

第二个内核为数字,相同的字节数:toeplitz([0 1 0])
Luis Mendo

2

我经常发现自己使用meshgridndgrid,假设我们要计算一个mandelbrot图像,然后初始化例如

[x,y]=meshgrid(-2:1e-2:1,-1:1e-2,1)

现在,对于mandelbrot集,我们需要另一个c大小为xy但用零初始化的矩阵。这可以通过编写以下代码轻松完成:

c=x*0;

您还可以将其初始化为另一个值:

c=x*0+3;

但是实际上您可以通过在以下位置添加另一个维度来节省一些字节meshgrid/ndgrid

[x,y,c]=meshgrid(-2:1e-2:1,-1:1e_2,1, 0); %or for the value 3
[x,y,c]=meshgrid(-2:1e-2:1,-1:1e_2,1, 3);

您可以根据需要执行以下操作:

[x,y,c1,c2,c3,c4,c5]=meshgrid(-2:1e-2:1,-1:1e_2,1, 1,pi,exp(3),1e5,-3i)

请注意,在此期间有自动广播:在许多情况下,第一个示例可以用代替x=-2:1d-2:1;y=x'
flawr

0

一系列功能的总和

  • 为了对函数f(x_n)求和,其中n是连续整数的向量,建议使用feval而不是symsum。

    Syms x;symsum(f(x),x,1,n);
    Sum(feval(@(x)f(x),1:n));
    

    请注意,基本操作.*./是代替成对的二进制操作*/

  • 如果该函数可以被天真地编写,则后一种方法都不适合。

    例如,如果函数是log,则可以简单地执行:sum(log(1:n)),它表示:

    Sum(f(1:n));
    

    可以使用相对复杂的功能log(n)/x^n

    Sum(log(1:n)./5.^(1:n))
    

    当一个功能甚至在某些情况下,较短不再作为f(x)=e^x+sin(x)*log(x)/x....

    Sum(feval(@(y)e.^(y)+sin(y).*log(y)./y,1:n))
    

    明显短于 sum(feval(@(y)e.^(1:n)+sin(1:n).*log(1:n)./(1:n),1:n))


注意:此技巧可以应用于其他包容性运算符,例如prodmean


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.