Получение кода для аналитической производной на Matlab - PullRequest
0 голосов
/ 20 мая 2019

У меня есть одна большая аналитическая функция myfunc.m, для которой мне нужно получить производную в кодовом формате d_myfunc_dx.m.Проблема заключается в том, что мне нужно создать код, который я могу реорганизовать, чтобы я мог соответствовать некоторым требованиям к качеству, и что сама функция имеет несколько особенностей, которые воспроизведены в минимальном примере ниже.

function[out] = myfunc(x,a, max_iterations)

count = 0;
theta = 0;
delta = 1;
while (count<max_iterations && abs(delta)<eps)
  cout = count+1;
  delta = theta - cos(theta*x);
  theta = theta - delta;
end

if(theta<a)
   out = theta+x
else
   out =  x
end

end

В идеале, производная функция должна выглядеть следующим образом:

function[d_out_dx] = myfunc(x,a, max_iterations)

count = 0;
theta = 0;
delta = 1;
while (count<max_iterations && abs(delta)<eps)
  cout = count+1;
  delta = theta - cos(theta*x);
  theta = theta - delta;
end

%assuming convergence: theta = cos(theta*x):
d_theta_dx = -theta*sin(theta*x);


if(theta>a)
   d_out_dx = d_theta_dx+1
else
   d_out_dx =  1
end

end

Т.е. это читабельно, поэтому я могу ее реорганизовать, она содержит ветви, которые присутствовали в исходной функции.Случай ребра theta=a игнорируется, что на самом деле желательно.

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

function[d_out_dx] = myfunc(x,a, max_iterations)

count = 0;
theta = 0;
delta = 1;
d_theta_dx = 0;
while (count<max_iterations && abs(delta) < eps)
  cout = count+1;
  delta = theta - cos(theta*x);
  d_delta_dx = d_theta_dx + theta*sin(theta*x)
  theta = theta - delta;
  d_theta_dx = d_theta_dx - d_delta_dx 
end

if(theta>a)
   d_out_dx = d_theta_dx+1
else
   d_out_dx =  1
end

end

Всегда приятно, если бы я мог найти какой-нибудь бесплатный инструмент для этой работы.

Я также должен проверить код, проверенный независимо, поэтому я буду знать, если что-то пошло не так.Не беспокойтесь о надежности инструмента.Из-за стандартов, применяемых при рефакторинге, я не буду беспокоиться о безопасности сгенерированного кода (т.е. о защите от деления на ноль).

То, что я пробовал до сих пор:

-Hand-Coding : Поскольку функции, с которыми мне нужно работать, очень велики, а процесс подвержен ошибкам, я просто не могу получить правильный код.Кроме того, мне нужно вычислить несколько переменных, что означает, что процесс будет слишком длительным.

-ADiMat : введены такие функции, как adimat_opdiff_mult (t_theta, theta, t_x,х), это заставляет меня не соблюдать мои стандарты кодирования.И рефакторинг это будет означать, что почти такая же работа, как и написание производных.

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

-Casadi: Насколько я экспериментировал с этим, он создает текствместо кода, и в этом тексте переменные, внутренние для функции, теряют свои имена и заменяются на @1, @2, @3 и так далее.Это было бы кошмаром для ручного перекодирования, и было бы трудно использовать собственный скрипт для его рефакторинга.

...