MATLABでのゴルフのヒント


14

MATLABでゴルフをするための一般的なヒントは何ですか?私は、ゴルフに関する一般的な問題のコード化に適用できる、MATLABに少なくともある程度固有のアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。回答ごとに1つのヒントを投稿してください。



回答:


9

ゴルフを始める前に知っておくべきこと:

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')
デニスジャエルディン

1
conv(1:5,[1 1],'s')代わりにconv(1:5,[1 1],'same')
ルイスメンドー

6

charとしてキャストするには、charと連結します。

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

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

保存される文字は1つだけですが、これは非常に頻繁に使用できます。



4

離散フーリエ変換による統一の根

正の整数を与えると、ユニティの -th 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)

しかし、離散フーリエ変換はさらに短い方法を提供します(2つの不要な括弧を削除してくれた@flawrに感謝します)。

fft(1:n==n)

1は正の角度方向から始まり、正の角度方向に移動します。または

fft(1:n==2)

で始まり1、負の角度方向に動きます。


ここで上記のすべてを試してください。


素晴らしいトリック!あなたもゴルフをすることができますfft(1:n==2)
flawr

@flawr優先ルールがわからない...ありがとう!
ルイスメンドー

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

私は実際にこれを「どれだけカウントできますか?」で 2回使用しました-チャレンジ:

strchr sssssssssssssst t

はに相当しstrchr('sssssssssssssst','t')、を返します15

nnz nnnnnnnnnnnnnn

はに相当しnnz('nnnnnnnnnnnnnn')、を返します14

gt r s作品のようなものも('r'>'s'またはに相当しgt('r','s')ます。


2

nnz 時には数バイト節約できます:

  • 論理行列の合計が必要だと想像してくださいAsum(sum(A))またはの代わりにsum(A(:))、使用できますnnz(a)nnz暗黙的に適用されます(:))。
  • 配列の要素数を知りたい場合、をnumel(x)使用する代わりにゼロがないことを確認できますnnz(x)。これはx、文字列の場合に適用可能です。

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

:数字、同じバイト数である第2のカーネルtoeplitz([0 1 0])
ルイスMendo

1

私は頻繁にmeshgridor ndgridを使用していることに気付きます。マンデルブロ画像を計算したいので、初期化する

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

今マンデルブロ集合のために、私たちは別のマトリックス必要cの大きさのをxしてyますがゼロで初期化。これは、次のように書くことで簡単に実行できます。

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)

1

ビルトイン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

これは、行列の1次元のサイズのゼロまたは1の列または行ベクトルを作成する場合にも機能します。

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)1次元のゼロベクトルに使用するのが好きです。
sintax

0

一連の関数の合計

  • nが連続する整数のベクトルである関数f(x_n)を合計するには、symsumではなくfevalが推奨されます。

    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))


注:このトリックは、prodまたは他の包括的演算子に適用できますmean


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.