2013-12-02 5 views
3

У меня есть код на C++, который взаимодействует с Matlab через API C Engine. Мой код создает временные переменные в рабочем пространстве Matlab, которые он усердно очищает по звонкам через clear как можно скорее. Однако в какой-то момент мое приложение выходит из строя, говоря, что он не может создать следующую временную переменную Matlab (обычно после ~ 65530 таких операций).Ограничение количества переменных Matlab

После некоторых экспериментов в командной строке Matlab я обнаружил, что могу воссоздать эту проблему в чистом Matlab (то есть независимо от моего кода на C++ и его использования API Engine). Рассмотрим следующий код:

for i = 1 : 100000 
    eval(sprintf('x_%d = %d', i, i)); 
    whos 
    eval(sprintf('clear x_%d', i)); 
    whos 
end 

Выполнение этого кода на моем 32-битном окна ноутбук с Matlab R2008B (древний, я знаю), петля в конце концов прерывается с сообщением об ошибке:

текущем рабочем пространстве уже слишком много переменных; нет места для "x_65532".

Итак, кажется, что, по крайней мере, эта устаревшая версия Matlab имеет предел таблицы символов 64K. Возможно, предел больше по сравнению с новыми (64-разрядными) версиями Matlab - мне было бы интересно узнать, какие результаты получат другие.

Тем не менее, более интересным вопросом является то, что вызывает звонок clear, и как обойти его странное поведение. Вот выход из итерации немного до прерывания:

x_65530 = 

     65530 

    Name   Size   Bytes Class  Attributes 

    i   1x1     8 double    
    x_65530  1x1     8 double    

    Name  Size   Bytes Class  Attributes 

    i   1x1     8 double    

Как вы можете видеть, whos выхода ясно показывает, что временные конструкции из предыдущих итераций, были удалены из рабочей области, и ясно, казалось бы, работы как и ожидалось. Тем не менее, таблица символов, очевидно, достигла пропускной способности.

Итак, два вопроса для так верно:

  1. Как я могу работать вокруг этого несколько произвольных ограничений? То есть, что должны заменить мои звонки clear?
  2. Изменилось ли это поведение с более новыми и/или 64-разрядными версиями Matlab?
+0

Можете ли вы рассказать больше о случаях использования, требующих так много временных переменных? P.S: вам не нужно 'eval' для первого' sprintf' внутри цикла ... –

+1

Реплицируемое в 2011b (32 бит) - точно такая же точка ошибки. Интересный бит заключается в том, что если я затем определяю дополнительные переменные в командной строке или повторно запускаю цикл, я не получаю ошибку (пока я не ударил эту точку цикла снова). – nkjt

+0

@EitanT: Случай использования: мой код на C++ обновляет график Matlab, отправляя ему множество новых данных в каждом фрейме. Вероятно, есть лучший способ сделать это, но он работает (по крайней мере, пока он не достигнет предела). Что же касается eval, вы уверены? Я явно пытаюсь создать переменную с алгоритмически выбранным, уникальным именем. Пропуск eval дал бы мне неназванную временную строку, нет? –

ответ

2

Повторяя мой комментарий в форме ответа:

Если вы должны придерживаться переменного наименования, вы могли бы попытаться повторно использовать имена переменных, как только они были очищены, избегая при этом созданий 65xxx различных имен переменных ,

1

Дело в том, что в Matlab вам не нужно иметь столько переменных. Используйте большие переменные, а не многие переменные.

Если каждый x является скаляр: использовать вектор

Если каждый x имеет тот же размер: использовать матрицу

Если каждый x отличается, использовать массив ячеек!

С x{65530} = magic(3) вы не будете находиться где-то ближе к пределу.

0

Я просто наткнулся на то же самое.Из Python я создаю временные переменные в экземпляре Matlab, которые позже очищаются. Чтобы убедиться, что я не переписывал другую временную переменную, я создал новые имена, используя модуль uuid() Python. Это должно было стать отличной идеей. Однако через некоторое время я получил исключение, с сообщением «В текущем рабочем пространстве уже слишком много переменных». Выполняя whos, я вижу, что это всего лишь 8 переменных, поэтому я должен заключить, что clear фактически не удаляет переменную из рабочей области. Это действительно трудно понять и действительно неудобно. Верно, что я могу использовать имена temp001, temp002, temp003, но тогда, когда мне нужна новая временная переменная, я должен убедиться, что я не использую это имя уже. Uuids были изобретены, чтобы избежать таких проблем, но, похоже, неловкое поведение Matlab мешает мне использовать их. Кто-нибудь нашел хорошее решение для ДЕЙСТВИТЕЛЬНО удалить переменные из рабочей области Matlab?

1

Ответ на вопрос 2) заключается в том, что это ограничение применяется к более старым версиям Matlab. Пока предел все еще присутствует в R2014b, его больше нет в R2015b.

Смежные вопросы