Mẹo chơi gôn trong MATLAB


14

Bạn có lời khuyên chung nào cho việc chơi golf trong MATLAB? Tôi đang tìm kiếm những ý tưởng có thể được áp dụng cho các vấn đề về golf nói chung ít nhất là cụ thể đối với MATLAB (ví dụ: "xóa bình luận" không phải là một câu trả lời). Xin vui lòng gửi một lời khuyên cho mỗi câu trả lời.


3
Liên quan, nhưng không phải là một bản sao: Mẹo chơi golf trong Octave
Dennis Jaheruddin

Câu trả lời:


9

Một cái gì đó mà người ta phải biết trước khi bắt đầu chơi golf:

Trong tính toán MATLAB, một ký tự hoạt động giống như mã ascii của nó.

'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

Rút ngắn tên tài sản

Trong MATLAB, các thuộc tính xác định chuỗi có thể được rút ngắn miễn là nó không dẫn đến sự mơ hồ.

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

Điều này thực sự đã thắng tôi một thử thách :)


2
Rất hay, mặc dù câu trả lời là đúng nhưng tôi muốn nhấn mạnh rằng điều này áp dụng cho tên của các name, valuecặp như hình trên. (Vì vậy, không phải những thứ như sort(rand(4,1),'descend'))
Dennis Jaheruddin

1
Nó cũng áp dụng cho một số trong những điều đó, như conv(1:5,[1 1],'s')thay vìconv(1:5,[1 1],'same')
Luis Mendo

6

Đúc như char có thể được thực hiện bằng cách ghép với char:

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

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

Mặc dù nó chỉ lưu một char, nhưng điều này có thể được sử dụng khá thường xuyên.


5

Chuỗi chỉ là các vectơ hàng ký tự. Điều này có nghĩa là thay vì

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

bạn chỉ có thể viết

for(a=str)
    ...
end

Lần đầu tiên tôi sử dụng cái này: /codegolf//a/58387/32352


4

Nguồn gốc của sự thống nhất thông qua biến đổi Fourier rời rạc

Cho một số nguyên dương n, cách tiêu chuẩn để tạo gốcn -th của sự thống nhất

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

Điều này cho rễ bắt đầu tại 1và di chuyển theo hướng góc tích cực. Nếu thứ tự không quan trọng, điều này có thể được rút ngắn thành

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

exp(2j*pi/4)bằng với đơn vị tưởng tượng ( j), nên điều này có thể được viết gọn hơn như sau (mẹo do @flawr ):

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

hoặc là

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

Nhưng biến đổi Fourier rời rạc cung cấp một cách thậm chí ngắn hơn (nhờ @flawr để loại bỏ hai dấu ngoặc đơn không cần thiết):

fft(1:n==n)

cung cấp cho rễ bắt đầu tại 1và di chuyển theo hướng góc tích cực; hoặc là

fft(1:n==2)

mà bắt đầu tại 1và di chuyển theo hướng góc âm.


Hãy thử tất cả những điều trên đây .


Thủ thuật tuyệt vời! Bạn thậm chí có thể đánh gôn xuốngfft(1:n==2)
flawr

@flawr Tôi không bao giờ biết các quy tắc ưu tiên ... Cảm ơn!
Luis Mendo

3

Lặp lại các vectơ trong ma trận.

Đưa ra một tập các vectơ dưới dạng ma trận, bạn thực sự có thể lặp lại chúng thông qua một vòng lặp for như

for v=M
    disp(v);
end

trong khi "theo truyền thống" bạn có thể đã làm nó như thế

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

Tôi mới chỉ biết về thủ thuật này từ @Suever trong thử thách này .


3

Lời khuyên liên quan, nhưng không giống nhau cho Octave .

Một tính năng ít được biết đến và ít được sử dụng của cả MATLAB và Octave là hầu hết các hàm dựng sẵn có thể được gọi mà không có dấu ngoặc đơn, trong trường hợp đó, chúng sẽ coi bất cứ thứ gì theo chuỗi đó (miễn là nó không chứa khoảng trắng). Nếu nó chứa khoảng trắng bạn cần dấu ngoặc kép. Điều này có thể thường xuyên được sử dụng để lưu một byte khi sử dụng disp:

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

Các ví dụ khác, ít hữu ích hơn bao gồm:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12

Tôi thực sự đã sử dụng điều này hai lần trong phần "Bạn có thể đếm cao đến mức nào?" -thử thách:

strchr sssssssssssssst t

tương đương strchr('sssssssssssssst','t')và trả về 15.

nnz nnnnnnnnnnnnnn

tương đương nnz('nnnnnnnnnnnnnn')và trả về 14.

Những thứ như gt r shoạt động quá (tương đương 'r'>'s'hoặc gt('r','s').


2

nnz đôi khi có thể giúp bạn tiết kiệm một vài byte:

  • Hãy tưởng tượng bạn muốn tổng của một ma trận logic A. Thay vì sum(sum(A))hoặc sum(A(:)), bạn có thể sử dụng nnz(a)( nnzáp dụng theo nghĩa đen (:)).
  • Nếu bạn muốn biết số lượng phần tử của một mảng và bạn có thể chắc chắn không có số không, thay vào đó numel(x)bạn có thể sử dụng nnz(x). Điều này được áp dụng ví dụ nếu xlà một chuỗi.

2

Hạt nhân 2D

Đây có thể là một chủ đề thích hợp, nhưng rõ ràng một số người thích sử dụng tích chập cho nhiều thứ khác nhau ở đây. [cần dẫn nguồn]

Trong nhân 2D sau thường là cần thiết:

0 1 0
1 1 1
0 1 0

Điều này có thể đạt được bằng cách sử dụng

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

cái nào ngắn hơn

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

Một kernel khác thường được sử dụng là

0 1 0
1 0 1
0 1 0

có thể rút ngắn bằng cách sử dụng

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

Hạt nhân thứ hai là số, cùng số byte:toeplitz([0 1 0])
Luis Mendo

1

Tôi thường thấy mình sử dụng meshgridhoặc ndgrid, giả sử chúng ta muốn tính toán một hình ảnh mandelbrot, sau đó chúng ta khởi tạo, ví dụ:

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

Bây giờ đối với bộ mandelbrot, chúng ta cần một ma trận khác ccó kích thước xynhưng được khởi tạo bằng số không. Điều này có thể dễ dàng được thực hiện bằng cách viết:

c=x*0;

Bạn cũng có thể khởi tạo nó thành một giá trị khác:

c=x*0+3;

Nhưng bạn thực sự có thể lưu một số byte bằng cách thêm một thứ nguyên khác vào 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);

Và bạn có thể làm điều này thường xuyên như bạn muốn:

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

1

Việc tích hợp oneszerosthường lãng phí không gian. Bạn có thể đạt được kết quả tương tự bằng cách nhân một mảng / ma trận (có kích thước mong muốn) với 0 (để lấy đầu ra của zeros) và thêm 1 nếu bạn muốn đầu ra của 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

Điều này cũng hoạt động nếu bạn muốn tạo một vectơ cột hoặc hàng 0 hoặc kích thước của một chiều của ma trận.

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

Nếu bạn muốn tạo một ma trận có kích thước cụ thể bạn có thể sử dụng zerosnhưng bạn cũng có thể chỉ định phần tử cuối cùng cho 0 và điền MATLAB vào phần còn lại.

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

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

2
Tôi thích sử dụng ~(1:n)cho các vectơ không 1-d.
sintax

0

Tổng hợp một chuỗi các chức năng

  • Để tính tổng các hàm f (x_n) trong đó n là một vectơ của các số nguyên liên tiếp, feval được khuyến khích thay vì symsum.

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

    Lưu ý rằng một hoạt động cơ bản .*./là cần thiết thay vì các hoạt động nhị phân cặp */

  • Nếu chức năng có thể được viết một cách ngây thơ, không ai trong hai cách cuối cùng là phù hợp.

    ví dụ: nếu hàm là logbạn có thể chỉ cần làm : sum(log(1:n)), đại diện cho:

    Sum(f(1:n));
    

    cho các chức năng tương đối tinh vi như log(n)/x^nbạn có thể làm:

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

    và thậm chí ngắn hơn trong một số trường hợp khi một hàm dài hơn f(x)=e^x+sin(x)*log(x)/x....

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

    nó ngắn hơn đáng kể so với sum(feval(@(y)e.^(1:n)+sin(1:n).*log(1:n)./(1:n),1:n))


Lưu ý: Thủ thuật này có thể được áp dụng cho các nhà khai thác bao gồm khác như prodhoặcmean


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.