Tips untuk bermain golf di MATLAB

14

Apa tips umum yang Anda miliki untuk bermain golf di MATLAB? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk MATLAB (mis. "Hapus komentar" bukan jawaban). Silakan kirim satu tip per jawaban.

RAM
sumber
3
Terkait, tetapi bukan duplikat: Tips untuk bermain golf di Oktaf
Dennis Jaheruddin
Fungsi
memoizing

Jawaban:

10

Sesuatu yang harus diketahui sebelum mulai bermain golf:

Dalam perhitungan MATLAB karakter berperilaku sama dengan kode ascii-nya.

'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)
Dennis Jaheruddin
sumber
9

Menyingkat nama properti

Dalam MATLAB, properti pengenal string dapat dipersingkat selama tidak menghasilkan ambiguitas.

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

Ini benar-benar memenangkan tantangan bagi saya :)

Sanchises
sumber
2
Sangat bagus, walaupun jawabannya benar saya ingin menekankan bahwa ini berlaku untuk nama name, valuepasangan seperti yang ditunjukkan di atas. (Jadi tidak untuk hal-hal seperti sort(rand(4,1),'descend'))
Dennis Jaheruddin
1
Itu memang berlaku untuk beberapa hal juga, seperti conv(1:5,[1 1],'s')bukannyaconv(1:5,[1 1],'same')
Luis Mendo
6

Casting sebagai char dapat dilakukan dengan penggabungan dengan char:

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

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

Meskipun hanya menghemat satu char, ini bisa digunakan cukup sering.

Dennis Jaheruddin
sumber
5

String hanyalah vektor baris karakter. Ini berarti bahwa alih-alih

for i=numel(str)
    a=str(i)
    ...
end

Anda cukup menulis

for(a=str)
    ...
end

Pertama kali saya menggunakan ini: /codegolf//a/58387/32352

Sanchises
sumber
4

Akar persatuan melalui transformasi Fourier diskrit

Diberikan bilangan bulat positif n, cara standar untuk menghasilkan akarn ke - ke -satu adalah

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

Ini memberikan akar mulai 1dan bergerak ke arah sudut positif. Jika pesanan tidak masalah, ini dapat dipersingkat menjadi

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

Karena exp(2j*pi/4)sama dengan unit imajiner ( j), ini dapat ditulis lebih kompak sebagai berikut (trik karena @ flawr ):

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

atau

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

Tetapi transformasi Fourier diskrit menyediakan cara yang lebih pendek (terima kasih kepada @ flawr karena menghapus dua tanda kurung yang tidak perlu):

fft(1:n==n)

yang memberikan akar mulai 1dan bergerak ke arah sudut positif; atau

fft(1:n==2)

yang dimulai pada 1 dan bergerak ke arah sudut negatif.


Coba semua hal di atas di sini .

Luis Mendo
sumber
Trik hebat! Anda bahkan dapat memasukkan golf kefft(1:n==2)
flawr
@ flawr Saya tidak pernah tahu aturan yang diutamakan ... Terima kasih!
Luis Mendo
3

nnz terkadang dapat menghemat beberapa byte:

  • Bayangkan Anda ingin jumlah matriks logis A. Alih-alih sum(sum(A))atau sum(A(:)), Anda dapat menggunakan nnz(a)(nnz berlaku secara tidak jelas (:)).
  • Jika Anda ingin mengetahui jumlah elemen dari sebuah array, dan Anda dapat yakin tidak ada nol, alih-alih numel(x)Anda dapat menggunakan nnz(x). Ini berlaku misalnya jika xadalah string.
Luis Mendo
sumber
3

Iterasi atas vektor dalam matriks.

Diberikan satu set vektor sebagai matriks, Anda sebenarnya dapat beralih atas mereka melalui satu untuk loop seperti

for v=M
    disp(v);
end

sementara "secara tradisional" Anda mungkin akan melakukannya seperti

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

Saya hanya belajar tentang trik ini sekarang dari @Suever dalam tantangan ini .

cacat
sumber
3

Terkait, tetapi bukan tip yang identik untuk Oktaf .

Fitur yang sedikit diketahui dan sedikit digunakan dari MATLAB dan Oktaf adalah bahwa sebagian besar fungsi builtin dapat dipanggil tanpa tanda kurung, dalam hal ini mereka akan memperlakukan apapun yang mengikutinya sebagai string (selama tidak mengandung spasi). Jika berisi spasi, Anda perlu tanda kutip. Ini sering dapat digunakan untuk menyimpan byte saat menggunakan disp:

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

Contoh lain yang kurang bermanfaat termasuk:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12

Saya sebenarnya telah menggunakan ini dua kali dalam "Seberapa tinggi Anda bisa menghitung?" -tantangan:

strchr sssssssssssssst t

setara dengan strchr('sssssssssssssst','t')dan kembali 15.

nnz nnnnnnnnnnnnnn

setara dengan nnz('nnnnnnnnnnnnnn')dan kembali 14.

Hal-hal seperti gt r sbekerja juga (setara dengan 'r'>'s'atau gt('r','s').

Stewie Griffin
sumber
2

Saya cukup sering menemukan diri saya menggunakan meshgridatau ndgrid, katakanlah kita ingin menghitung gambar mandelbrot, lalu kita inisialisasi misalnya

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

Sekarang untuk set mandelbrot kita perlu matriks lain cdari ukuran xdan ytetapi diinisialisasi dengan nol. Ini dapat dengan mudah dilakukan dengan menulis:

c=x*0;

Anda juga dapat menginisialisasi ke nilai lain:

c=x*0+3;

Tetapi Anda sebenarnya dapat menyimpan beberapa byte dengan hanya menambahkan dimensi lain di 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);

Dan Anda dapat melakukan ini sesering yang Anda inginkan:

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

Built-in onesdan zerosbiasanya merupakan pemborosan ruang. Anda dapat mencapai hasil yang sama hanya dengan mengalikan array / matriks (dari ukuran yang diinginkan) dengan 0 (untuk mendapatkan output zeros) dan menambahkan 1 jika Anda menginginkan output 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

Ini juga berfungsi jika Anda ingin membuat kolom atau vektor baris nol atau yang ukuran satu dimensi dari matriks.

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

Jika Anda ingin membuat matriks dengan ukuran tertentu yang bisa Anda gunakan zerostetapi Anda juga bisa menetapkan elemen terakhir ke 0 dan minta MATLAB mengisi sisanya.

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

%// vs. This
z(2,3) = 0;
Suever
sumber
2
Saya suka menggunakan ~(1:n)untuk vektor nol 1-d.
sintax
2

Kernel Konvolusi 2D

Ini mungkin topik khusus, tetapi tampaknya beberapa orang suka menggunakan konvolusi untuk berbagai hal di sini. [rujukan?]

Dalam 2D, kernel berikut sering dibutuhkan:

0 1 0
1 1 1
0 1 0

Ini bisa dicapai dengan menggunakan

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

yang lebih pendek dari

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

Kernel lain yang sering digunakan adalah

0 1 0
1 0 1
0 1 0

yang dapat disingkat menggunakan

v=[1,-1,1];v'*v<0   % logical
[0,1,0;1,0,1;0,1,0] % naive verison
cacat
sumber
Kernel kedua sebagai angka, jumlah byte yang sama:toeplitz([0 1 0])
Luis Mendo
0

Penjumlahan dari serangkaian fungsi

  • Untuk meringkas fungsi f (x_n) di mana n adalah vektor bilangan bulat berturut-turut, feval disarankan daripada symsum.

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

    Perhatikan bahwa operasi dasar .*dan ./diperlukan bukan operasi biner berpasangan *dan/

  • Jika fungsinya dapat ditulis secara naif, tidak ada seorang pun dari kedua cara terakhir yang cocok.

    misalnya jika fungsinya logAnda cukup lakukan:, sum(log(1:n))yang mewakili:

    Sum(f(1:n));
    

    untuk fungsi yang relatif canggih yang log(n)/x^ndapat Anda lakukan:

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

    dan bahkan lebih pendek dalam beberapa kasus ketika suatu fungsi lebih panjang f(x)=e^x+sin(x)*log(x)/x....

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

    itu jauh lebih pendek dari sum(feval(@(y)e.^(1:n)+sin(1:n).*log(1:n)./(1:n),1:n))


Catatan: Trik ini dapat diterapkan untuk operator inklusif lainnya sebagai prodataumean


Abr001am
sumber