Угловые шкафы, неожиданные и необычные MATLAB

На протяжении многих лет, читая чужой код, я столкнулся и собрал несколько примеров синтаксиса MATLAB, который может быть поначалу необычным и нелогичным. Пожалуйста, не стесняйтесь комментировать или дополнять этот список. Я проверил это с r2006a.


MATLAB всегда возвращает первый выходной аргумент функции (если он имеет хотя бы один) в рабочее пространство вызывающей стороны, также неожиданно, если функция вызывается без возврата таких аргументов, как myFunc1(); myFunc2(); рабочая область вызывающего абонента все еще будет содержать первый вывод myFunc2(); как "невидимый" ans переменная. Это может сыграть важную роль, если ans является эталонным объектом - он останется живым.


set([], 'Background:Color','red')

MATLAB иногда очень прощающий. В этом случае установка свойств для массива объектов работает также с бессмысленными свойствами, по крайней мере, когда массив пуст. Такие массивы обычно приходят из harray = findobj(0,'Tag','NotExistingTag')


myArray([1,round(end/2)])

Это использование end Ключевое слово может показаться нечистым, но иногда очень удобно вместо length(myArray),


any([]) ~= all([])

Surprisigly any([]) возвращается false а также all([]) возвращается true, И я всегда думал, что all сильнее any,

РЕДАКТИРОВАТЬ:

с не пустым аргументом all() возвращается true для подмножества значений, для которых any() возвращается true (например, таблица истинности). Это означает, что any()false подразумевает all()false, Это простое правило нарушается MATLAB с [] в качестве аргумента.

Лорен также написал об этом в блоге.


Select(Range(ExcelComObj))

Процедура отправки COM-объекта в стиле процедур. Не удивляйся что exist('Select') возвращает ноль!


[myString, myCell]

В этом случае MATLAB делает неявное приведение строковой переменной myString на тип клетки {myString}, Это работает, даже если я не ожидал, что это так.


[double(1.8), uint8(123)] => 2 123

Еще один пример. Все, вероятно, ожидают uint8 значение приведено к double но у Mathworks есть другое мнение. Без предупреждения это поведение очень опасно.


a = 5;
b = a();

Это выглядит глупо, но вы можете вызвать переменную в круглых скобках. На самом деле это имеет смысл, потому что таким образом вы можете выполнить функцию, учитывая ее дескриптор.


Синтаксис Foo(:) работает не только с данными, но и с функциями, если они называются Bar.Foo(:)в этом сценарии входной аргумент функции передается как двоеточие ':',

Например пусть Bar.Foo = @(x) disp(x)Сейчас звоню Bar.Foo(:) печатает чар ':' в командном окне MATLAB.

Эта странная функция работает со всеми версиями MATLAB 7 без предупреждений.


a = {'aa', 'bb'
'cc', 'dd'};

Удивительно, но этот код не возвращает вектор и не вызывает ошибку, а определяет матрицу, используя только компоновку кода. Это, вероятно, реликт с древних времен.

РЕДАКТИРОВАТЬ: очень удобная функция, см. Комментарий от gnovice.


set(hobj, {'BackgroundColor','ForegroundColor'},{'red','blue'})

Этот код делает то, что вы, вероятно, ожидаете. Эта функция set принимает структуру, поскольку ее второй аргумент является известным фактом и имеет смысл, а этот синтаксис является просто cell2struct далеко.


Правила эквивалентности поначалу иногда бывают неожиданными. Например 'A'==65 возвращает true (хотя для C-специалистов это очевидно). так же isequal([],{}) повторы, как и ожидалось, false а также isequal([],'') возвращается true,

Строково-числовая эквивалентность означает, что все строковые функции можно использовать также для числовых массивов, например, для поиска индексов подмассива в большом массиве:

ind = strfind( [1 2 3 4 1 2 3 4 1 2 3 4 ], [2 3] )

Функция MATLAB isnumeric() возвращается false для логических значений. Это кажется просто... ложным:-)


О каких еще неожиданных / необычных функциях MATLAB вам известно?

3 ответа

Координаты изображения против координат графика Используется, чтобы получить меня каждый раз.

%# create an image with one white pixel
img = zeros(100);
img(25,65) = 1;

%# show the image
figure
imshow(img);

%# now circle the pixel. To be sure of the coordinate, let's run find
[x,y] = find(img);
hold on
%# plot a red circle...
plot(x,y,'or')
%# ... and it's not in the right place

%# plot a green circle with x,y switched, and it works
plot(y,x,'og')

Редактировать 1

Размеры массива

Переменные имеют как минимум два измерения. Скаляры размерные [1,1], векторы размером [1,n] или же [n,1], Таким образом, ndims возвращает 2 для любого из них (на самом деле, ndims([]) 2, так как size([]) является [0,0]). Это немного затрудняет проверку на размерность вашего ввода. Чтобы проверить одномерные массивы, вы должны использовать isvector, Нужны массивы 0D isscalar,

Редактировать 2

Массив назначений

Обычно Matlab строго присваивает массивы. Например

m = magic(3);
m(1:2,1:3) = zeros(3,2);

бросает

??? Subscripted assignment dimension mismatch.

Тем не менее, эти работы:

m(1:2,1:2) = 1; %# scalar to vector
m(2,:) = ones(3,1); %# vector n-by-1 to vector 1-by-n (for newer Matlab versions)
m(:) = 1:9; %# vector to 'linearized array'

Редактировать 3

Логическая индексация с массивами неправильного размера Удачи в отладке!

Логическая индексация, кажется, призывает find, поскольку вашему логическому массиву не нужно столько же элементов, сколько есть индексов!

>> m = magic(4); %# a 4-by-4 array
>> id = logical([1 1 0 1 0])
id =
     1     1     0     1     0
>> m(id,:)  %# id has five elements, m only four rows
ans =
    16     2     3    13
     5    11    10     8
     4    14    15     1
%# this wouldn't work if the last element of id was 1, btw

>> id = logical([1 1 0])
id =
     1     1     0
>> m(id,:) %# id has three elements, m has four rows
ans =
    16     2     3    13
     5    11    10     8

Вместо того, чтобы перечислять примеры странного синтаксиса MATLAB, я рассмотрю некоторые примеры в вопросе, которые, на мой взгляд, имеют смысл или являются ожидаемым / задокументированным / желаемым поведением.

  • Как ЛЮБЫЕ и ВСЕ обрабатывают пустые аргументы:

    Результат any([]) имеет смысл: во входном векторе нет ненулевых элементов (поскольку он пуст), поэтому он возвращает false.

    Результат all([]) лучше понять, подумав о том, как реализовать свою версию этой функции:

    function allAreTrue = my_all(inArray)
      allAreTrue = true;
      N = numel(inArray);
      index = 1;
      while allAreTrue && (index <= N)
        allAreTrue = (inArray(index) ~= 0);
        index = index + 1;
      end
    end
    

    Эта функция перебирает элементы inArray пока он не встретит тот, который равен нулю. Если inArray пусто, цикл никогда не вводится и значение по умолчанию allAreTrue возвращается

  • Объединение в отличие от классов:

    При объединении разных типов в один массив MATLAB следует заданному приоритету классов и соответствующим образом преобразует значения. Общий порядок приоритетов (от высшего к низшему): char, integer (любого знака или количества бит), single, double, а также logical, Вот почему [double(1.8), uint8(123)] дает вам результат типа uint8, При объединении в отличие от целочисленных типов (uint8, int32 и т. д.), крайний левый матричный элемент определяет тип результата.

  • Несколько строк без использования оператора продолжения строки ( ... ):

    При построении матрицы с несколькими строками вы можете просто нажать клавишу возврата после ввода одной строки и ввести следующую строку на следующей строке, не используя точку с запятой для определения новой строки или ... продолжить линию. Следовательно, следующие объявления эквивалентны:

    a = {'aa', 'bb'
    'cc', 'dd'};
    
    a = {'aa', 'bb'; ...
    'cc', 'dd'};
    
    a = {'aa', 'bb'; 'cc', 'dd'};
    

    Почему вы хотите, чтобы MATLAB вел себя так? Одна из причин, которую я заметил, заключается в том, что это позволяет легко вырезать и вставлять данные, например, из документа Excel в переменную в командном окне MATLAB. Попробуйте следующее:

    • Выберите регион в файле Excel и скопируйте его.
    • Тип a = [ в MATLAB, не нажимая возврата.
    • Щелкните правой кнопкой мыши командное окно MATLAB и выберите "Вставить".
    • Тип ]; и ударил в ответ. Теперь у вас есть переменная a который содержит данные из строк и столбцов, выбранных вами в файле Excel, и который поддерживает "форму" данных.

Массивы против клеток

Давайте посмотрим на некоторый основной синтаксис для начала. Для создания массива с элементами a, b, c вы пишете [a b c], Чтобы создать ячейку с массивами A, B, C, вы пишете {A B C}, Все идет нормально.

Доступ к элементам массива осуществляется следующим образом: arr(i), Для клеток это cell{i}, Все еще хорош.

Теперь давайте попробуем удалить элемент. Для массивов: arr(i) = [], Экстраполируя приведенные выше примеры, вы можете попробовать cell{i} = {} для ячеек, но это синтаксическая ошибка. Правильный синтаксис для удаления элемента ячейки, по сути, тот же самый синтаксис, который вы используете для массивов: cell(i) = [],

Таким образом, большую часть времени вы обращаетесь к ячейкам, используя специальный синтаксис, но при удалении элементов вы используете синтаксис массива.

Если вы покопаетесь глубже, вы обнаружите, что на самом деле ячейка - это массив, в котором каждое значение имеет определенный тип. Так что вы все еще можете написать cell(i), вы просто получите {A} (однозначная ячейка!) назад. cell{i} это сокращение, чтобы получить A непосредственно.

Все это не очень симпатичное ИМО.

Другие вопросы по тегам