MATLAB'da golf için ipuçları


14

MATLAB'da golf yapmak için hangi genel ipuçlarınız var? Genel olarak en azından biraz MATLAB (örneğin "yorumları kaldırmak" bir cevap değildir) özel olan golf sorunları kod uygulanabilir uygulanabilir fikirler arıyorum. Lütfen cevap başına bir ipucu gönderin.


3
İlgili, ancak yinelenen değil:
Octave'de

Yanıtlar:


10

Golf oynamaya başlamadan önce bilmeniz gereken bir şey:

MATLAB hesaplamalarında bir karakter ascii koduyla aynı şekilde davranır.

'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

Mülk adlarını kısaltma

MATLAB'da, özellikleri tanımlayan dizeler belirsizliğe neden olmadıkça kısaltılabilir.

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

Bu aslında bana bir meydan okuma kazandı :)


2
Çok güzel, cevap doğru olsa da, bunun name, valueyukarıda gösterildiği gibi çiftler için geçerli olduğunu vurgulamak istiyorum . (Öyle şeylere değil sort(rand(4,1),'descend'))
Dennis Jaheruddin

1
Bu gibi bazı şeyler için de geçerli, conv(1:5,[1 1],'s')bunun yerineconv(1:5,[1 1],'same')
Luis Mendo

6

Karakter olarak döküm, karakterle birleştirilerek yapılabilir:

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

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

Sadece bir karakter kaydetmesine rağmen, bu oldukça sık kullanılabilir.


5

Dizeler sadece karakter sırası vektörleridir. Bu demek oluyor ki

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

sadece yazabilirsin

for(a=str)
    ...
end

Bunu ilk kullandığımda: /codegolf//a/58387/32352


4

Ayrık Fourier dönüşümü ile birliğin kökleri

Pozitif tam sayı göz önüne alındığında n, standart yol oluşturmak için noyunu bırakanların birlik köklerini olduğu

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

Bu, köklerin 1pozitif açısal yönde başlayıp hareket etmesini sağlar. Sipariş önemli değilse, bu kısaltılabilir

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

Yana exp(2j*pi/4)(hayali birimine karşılık j), bu daha kompakt (hile aşağıdaki gibi yazılabilir @flawr nedeniyle ):

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

veya

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

Ancak ayrık Fourier dönüşümü daha da kısa bir yol sağlar (iki gereksiz parantezin kaldırılması için @flawr sayesinde):

fft(1:n==n)

bu 1, pozitif açısal yönde başlayıp hareket eden kökleri verir ; veya

fft(1:n==2)

1negatif açısal yönde başlar ve hareket eder.


Yukarıdakilerin hepsini burada deneyin .


Harika numara! Hatta golf aşağı olabilirfft(1:n==2)
flawr

@flawr Öncelik kurallarını asla bilmiyorum ... Teşekkürler!
Luis Mendo

3

nnz bazen birkaç bayt tasarruf edebilir:

  • Mantıksal bir matrisin toplamını istediğinizi düşünün A. sum(sum(A))Ya da yerine sum(A(:))kullanabilirsiniz nnz(a)( nnzaçıkça uygulanır (:)).
  • Bir dizinin eleman sayısını bilmek istiyorsanız ve bunun yerine sıfırlar olmadığından emin numel(x)olabilirsiniz nnz(x). Bu, örneğin xbir dize olduğunda geçerlidir .

3

Matrislerde vektörler üzerinde yineleme.

Matris olarak bir vektör kümesi verildiğinde, aslında bir döngü için

for v=M
    disp(v);
end

"geleneksel" olsa muhtemelen

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

Ben sadece bu meydan okuma sadece @Suever bu hile hakkında öğrendim .


3

İlgili, ancak Octave için aynı ipuçları değil .

Hem MATLAB hem de Octave'nin az bilinen ve az kullanılan bir özelliği, çoğu yerleşik fonksiyonun parantez olmadan çağrılabilmesi, bu durumda onu takip eden her şeyi bir dize olarak (boşluk içermediği sürece) ele alacaklarıdır. Boşluklar içeriyorsa, tırnak işaretlerine ihtiyacınız vardır. Bu genellikle aşağıdakileri kullanırken bir bayt kaydetmek için kullanılabilir disp:

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

Diğer, daha az kullanışlı örnekler şunları içerir:

nnz PPCG
ans = 4

size PPCG
ans = 1  4

str2num 12
ans = 12

Aslında bunu "Ne kadar sayabilirsin?" -meydan okuma:

strchr sssssssssssssst t

eşittir strchr('sssssssssssssst','t')ve geri döner 15.

nnz nnnnnnnnnnnnnn

eşittir nnz('nnnnnnnnnnnnnn')ve geri döner 14.

gt r sİşler gibi şeyler de ( 'r'>'s'ya da eşdeğeri) gt('r','s').


2

Yerleşik onesve zerostipik olarak bir alan kaybıdır. Bir diziyi / matrisi (istenen boyutta) 0 ile çarparak (çıktısını almak için) aynı sonucu elde edebilir ve çıktısını zerosistiyorsanız 1 ekleyebilirsiniz 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

Bu, sıfırların veya matrisin bir boyutunun boyutlarının sütun veya satır vektörünü oluşturmak istiyorsanız da işe yarar.

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

Belirli bir boyutta bir matris oluşturmak istiyorsanız, zerosancak son öğeyi 0'a atayabilir ve geri kalanını MATLAB doldurabilirsiniz.

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

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

2
~(1:n)1-d sıfır vektörleri için kullanmayı seviyorum .
sintax

2

2D Evrişim Çekirdekleri

Bu belki niş bir konu, ama görünüşe göre bazı insanlar burada çeşitli şeyler için evrişim kullanmayı seviyorlar. [kaynak belirtilmeli]

2D'de genellikle aşağıdaki çekirdeklere ihtiyaç vardır:

0 1 0
1 1 1
0 1 0

Bu,

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

ki bu daha kısa

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

Sık kullanılan başka bir çekirdek

0 1 0
1 0 1
0 1 0

kullanılarak kısaltılabilir

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

Sayı olarak ikinci çekirdek, aynı bayt sayısı:toeplitz([0 1 0])
Luis Mendo

2

Kendimi sık sık kullanıyorum meshgridveya ndgridmandelbrot görüntüsünü hesaplamak istediğimizi varsayalım, o zaman

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

Şimdi mandelbrot kümesi için başka bir matris ihtiyacımız cboyutunun xve yancak sıfırlarla başlatıldı. Bu yazı yazarak kolayca yapılabilir:

c=x*0;

Ayrıca başka bir değere de başlatabilirsiniz:

c=x*0+3;

Ancak, yalnızca başka bir boyut ekleyerek bazı baytları kaydedebilirsiniz 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);

Ve bunu istediğiniz sıklıkta yapabilirsiniz:

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

Bu arada otomatik yayın olduğunu unutmayın: Çoğu durumda ilk örnek ile değiştirilebilir x=-2:1d-2:1;y=x'.
flawr

0

Bir fonksiyon dizisinin toplamı

  • N'nin ardışık tamsayıların bir vektörü olduğu f (x_n) fonksiyonlarının toplanması için, fundam, symsum yerine tavsiye edilir.

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

    Bildirim temel bir işlem olduğunu .*ve ./bunun yerine ikişerli ikili operasyonların gereklidir *ve/

  • Eğer işlev naif olarak yazılabilirse, son iki yoldan hiç kimse uygun değildir.

    Örneğin fonksiyon ise logsadece yapabilirsiniz: sum(log(1:n)), temsil ettiği:

    Sum(f(1:n));
    

    log(n)/x^nyapabileceğiniz gibi nispeten karmaşık işlevler için:

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

    ve hatta bazı durumlarda daha kısa bir işlev daha uzun olarak olduğunda f(x)=e^x+sin(x)*log(x)/x....

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

    bu dikkate değer ölçüde daha kısa sum(feval(@(y)e.^(1:n)+sin(1:n).*log(1:n)./(1:n),1:n))


Not: Bu hile, diğer kapsayıcı operatörler için prodveyamean


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.