Оцените изменяющуюся функцию в цикле

Я пишу код, который генерирует функцию f в цикле. Эта функция f изменяется в каждом цикле, например, с f = x + 2x на f = 3x^2 + 1 (случайным образом), и я хочу оценивать f в разных точках каждого цикла. Я пытался использовать subs, eval, matlabFunction и т. д., но он все еще работает медленно. Как бы вы решили подобную проблему наиболее эффективным способом?

Это так быстро, как я был в состоянии сделать это. ****matlabFunction и сабвуферы работают медленнее, чем это. Код ниже - это мое решение, и это один цикл. В моем более крупном коде функция f и точка x0 меняются в каждом цикле, поэтому вы можете себе представить, почему я хочу, чтобы это выполнялось как можно быстрее. Я был бы очень признателен, если бы кто-то мог пройти через это и дать мне какие-либо указатели. Если мой код дерьмовый, не стесняйтесь сказать мне: D

x = sym('x',[2,1]);
f = [x(1)-x(1)cos(x(2)), x(2)-3x(2)^2*cos(x(1))];
J = jacobian(f,x);
x0 = [2,1];
N=length(x0); % Number of equations

%% Transform into string
fstr = map2mat(char(f));
Jstr = map2mat(char(J));

% replace every occurence of 'xi' with 'x(i)'
Jstr = addPar(Jstr,N);
fstr = addPar(fstr,N);

x = x0;

phi0 = eval(fstr)
J = eval(Jstr)

function str = addPar(str,N)

% pstr = addPar(str,N)
% Transforms every occurence of xi in str into x(i)
% N is the maximum value of i
% replace every occurence of xi with x(i)
% note that we do this backwards to avoid x10 being
% replaced with x(1)0

for i=N:-1:1
is = num2str(i);
xis = ['x' is];
xpis = ['x(' is ')'];
str = strrep(str,xis,xpis);
end

function r = map2mat(r)

% MAP2MAT Maple to MATLAB string conversion.
% Lifted from the symbolic toolbox source code
% MAP2MAT(r) converts the Maple string r containing
% matrix, vector, or array to a valid MATLAB string.
%
% Examples: map2mat(matrix([[a,b], [c,d]]) returns
% [a,b;c,d]
% map2mat(array([[a,b], [c,d]]) returns
% [a,b;c,d]
% map2mat(vector([[a,b,c,d]]) returns
% [a,b,c,d]
% Deblank.

r(findstr(r,' ')) = [];

% Special case of the empty matrix or vector
if strcmp(r,'vector([])') | strcmp(r,'matrix([])') | ...
strcmp(r,'array([])')
r = [];
else
% Remove matrix, vector, or array from the string.
r = strrep(r,'matrix([[','['); r = strrep(r,'array([[','[');
r = strrep(r,'vector([','['); r = strrep(r,'],[',';');
r = strrep(r,']])',']'); r = strrep(r,'])',']');
end

person Kristoffer Lindvall    schedule 11.01.2016    source источник
comment
Поскольку вы работаете в Matlab, вам нужно добавить тег matlab к своему вопросу.   -  person Robert Dodier    schedule 12.01.2016


Ответы (1)


Есть несколько способов получить значительное увеличение скорости для такого рода проблем:

  • Внешний интерфейс java GUI замедляет работу. Вернитесь к версии 2010a или более ранней. Вернитесь к тому времени, когда он был основан на C или Fortran. Сценарий MATLAB работает так же быстро, как если бы вы поместили его в «компилятор» MATLAB.
  • Если у вас есть компилятор MatLab (или сборщик, я забыл какой), но нет кодера, вы можете обработать свой код и заставить его работать в несколько раз быстрее, не изменяя код.
  • записать его в файл, а затем вызвать как функцию. Я сделал это для изменения выражений конечных элементов, такой большой уродливой математики, что $y = 3x^2 +1$ выглядит просто. В том, что это дало мне солидный прирост скорости.
  • векторизировать, векторизировать, векторизировать. Раньше он надежно увеличивал скорость от 10 до 12 раз. Вытяните его из петель. Java, я думаю, скрывает это, делая все медленнее.
  • Вы «профилировали» свою функцию, чтобы убедиться, что «eval» или что-то в этом роде является проблемой? Если вы исправите «eval», а ваше узкое место находится в другом месте, у вас возникнут проблемы.
  • Если у вас есть выбор между eval и subs, придерживайтесь eval. subs дает вам символическое решение, а не числовое.
  • Если есть чистый способ запустить несколько экземпляров MatLab, особенно если у вас есть прилично многоядерный процессор, который MatLab не использует полностью, тогда запустите несколько из них. Если вы работаете в образовательном учреждении, вы можете попробовать запустить несколько разных версий (2010a, 2010b, 2009a,...) в одной системе. Я (смутно) припоминаю, что они не столкнулись, когда я это делал. Запуск более 8 начал замедлять работу, а не улучшать ее. Убедитесь, что они не конфликтуют при доступе к файлам, если вы используете файлы для совместного управления.
  • Вы можете написать свою программу в LabVIEW (не MathScript, не MatLab), и поскольку это компилируемый язык, иногда код может работать в 1000 раз быстрее.
  • Вы можете перейти ко всем цифрам и сделать это матричным действием. Это зависит от вашего кода, но если бы вы могли случайным образом заполнить столбцы в матрице, а затем умножить матрицу на матрицу $\left[1, x, x^{2}, ...\right] $, это, вероятно, будет в несколько сотен или тысяч раз быстрее, чем ваш текущий уровень обработки уравнений, и все еще в MatLab.

О вашем кодировании:

  • не переопределяйте «x» как символ в каждом цикле, это дорого.
  • что это за "map2mat" и "addPar"?
  • функции обработки строк ужасны для времени выполнения. Придерживайтесь одного языка. Символический набор инструментов ЯВЛЯЕТСЯ Maple, и вам не нужно заниматься дурацким самодельным синтаксическим анализом, чтобы заставить его работать с остальной частью MatLab.
person EngrStudent    schedule 25.01.2016