Советы по игре в гольф в MATLAB


14

Какие общие советы у вас есть для игры в гольф в MATLAB? Я ищу идеи, которые могут быть применены к задачам по коду для гольфа в целом, которые, по крайней мере, несколько специфичны для MATLAB (например, «удалить комментарии» - это не ответ). Пожалуйста, оставьте один совет за ответ.


3
Связанный, но не дубликат: Советы по игре в гольф в
Октаве

Ответы:


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'))
Деннис Джаэруддин

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

Хотя он сохраняет только один символ, его можно использовать довольно часто.


5

Строки - это просто векторы строк символов. Это означает, что вместо

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

ты можешь просто написать

for(a=str)
    ...
end

Впервые я использовал это: /codegolf//a/58387/32352


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

@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

Встроенный onesи zeros, как правило, пустая трата пространства. Вы можете достичь того же результата, просто умножив массив / матрицу (нужного размера) на 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)для 1-й нулевой векторов.
синтаксис

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])
Луис Мендо

2

Я довольно часто использую meshgridили 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)

Обратите внимание, что в то же время существует автоматическое вещание: во многих случаях первый пример может быть заменен на 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))


Примечание: этот трюк может быть применен к другим инклюзивным операторам как prodилиmean


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.