Как использовать конструкцию переключателя со строками переменной длины в Embedded Matlab?

Мне никогда особо не нравился Embedded MATLAB именно из-за ситуаций, подобных тому, о чем я собираюсь спросить :) По моему опыту, преобразование в Embedded MATLAB часто требует гораздо больше усилий, чем простое переписывание на C (когда вы знаете C и API MATLAB достаточно хорошо).

Но да ладно, я думаю, некоторых вещей просто нельзя избежать.

Во всяком случае, вот моя проблема. В Embedded MATLAB, как и в R2010a, вы не можете сделать это:

for ii = <some range>

    parameter = <some string> 

    switch parameter

        case 'first_string'
            % do stuff

        case 'another_string_that''s_larger_than_first_string'
            % do other stuff
    end

    % ...continue here

end

где <some string> меняется каждую итерацию. Это связано с тем, что длина строки parameter является переменной, а это означает, что это определение parameter выходит за рамки возможностей Embedded Matlab:

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

Изменение switch на его более прямую форму

switch <some string> 
    ...
end

не помогает конечно:

??? Expected a numeric value. Found a mxArray

Даже ограничение размера строки известной постоянной длиной не помогает:

parameter = char_array(ii, 1:4);  % <--- NOTE: length is 4 characters

switch parameter
    ...
end

но не повезло:

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

Я вижу два выхода:

  1. Сопоставьте все допустимые строки с некоторым числовым представлением и используйте переключатель на числах
  2. Используйте strcmp(i) внутри огромной конструкции if-elseif-elseif-...-else-end.

Оба одинаково уродливы, ИМХО, причем 2., возможно, уродливее (вам понадобится еще одна внешняя функция, strcmp)...

Итак, есть ли из этого какой-нибудь элегантный выход?


person Rody Oldenhuis    schedule 12.06.2013    source источник
comment
Я думаю, сработает дополнение строки пробелом до равной длины? (Однако это не элегантное решение, которое вы искали.)   -  person user1884905    schedule 12.06.2013
comment
@ user1884905: нет, я пробовал... на самом деле, в моей реальной функции первые 4 символа однозначно определяют строки, поэтому я попытался использовать только первые 4 символа; не повезло, такое же сообщение об ошибке.   -  person Rody Oldenhuis    schedule 12.06.2013


Ответы (1)


К сожалению, я не знаю другого метода, кроме упомянутых вами альтернатив.

Что еще хуже, MATLAB не имеет встроенного массива символов для удвоения скалярной хеш-функции. Следовательно, если вы хотите сопоставить строки с числами, вам необходимо предоставить пользовательскую хеш-функцию.

Лично я бы пошел с вашим вторым методом. Это некрасиво, но читабельно.

Поскольку вы говорите, что вам нужно учитывать только первые 4 символа каждой строки, другим вариантом сопоставления ваших строк с числами является явный поиск:

function y = fcn(u)
%#codegen

    y = u;

    cases = [
        '1111'
        '2222'
        '3333'
    ];

    for i = 1 : 3
        switch i
            case 1                
                p = '1111a';
            case 2
                p = '2222bb';
            otherwise
                p = '3333ccc';
        end      

        for j = 1 : size(cases, 1)
            if isequal(cases(j, 1 : 4), p)
                switch j
                    case 1
                        y = y + 1;
                    case 2
                        y = y + 2;
                    case 3
                        y = y + 3;
                end
            end
        end        
    end
end

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

person Florian Brucker    schedule 12.06.2013
comment
Спасибо, этого я и боялся. Я решил это с помощью уродливой конструкции if-elseif-...-else-end, которую я считал действительно наиболее читаемой альтернативой. Сопоставление строк с каким-то произвольным числом было немного похоже на то, как заставить Volkswagen Beetle выйти на низкую околоземную орбиту... просто немного за пределами его конструктивных ограничений :) - person Rody Oldenhuis; 12.06.2013