Deixe-me pesar aqui com algumas palavras de cautela, precedidas de uma história. Há muito tempo, eu trabalhava com um colega quando estava começando. Ele tinha um problema de otimização a resolver, com um objetivo bastante confuso. Sua solução foi gerar os derivados analíticos para uma otimização.
O problema que eu vi foi que esses derivados eram desagradáveis. Gerados usando Macsyma, convertidos em código fortran, cada um deles tinha dezenas de instruções de continuação. De fato, o compilador Fortran ficou chateado com isso, pois excedeu o número máximo de instruções de continuação. Embora tenhamos encontrado uma bandeira que nos permitiu contornar esse problema, houve outros problemas.
Em expressões longas, como geralmente são geradas pelos sistemas de CA, existe o risco de cancelamento subtrativo maciço. Calcule muitos números grandes, apenas para descobrir que todos se cancelam para produzir um número pequeno.
Geralmente, os derivativos gerados analiticamente são mais caros para avaliar do que os derivados numericamente gerados usando diferenças finitas. Um gradiente para n variáveis pode levar mais que n vezes o custo de avaliar sua função objetivo. (Você pode economizar algum tempo porque muitos dos termos podem ser reutilizados nos vários derivados, mas isso também o forçará a fazer uma codificação manual cuidadosa, em vez de usar expressões geradas por computador. E sempre que codificar matemática desagradável expressões, a probabilidade de um erro não é trivial. Verifique se essas derivações estão corretas.)
O ponto da minha história é que essas expressões geradas pela CA têm problemas próprios. O engraçado é que meu colega estava realmente orgulhoso da complexidade do problema, que estava resolvendo claramente um problema realmente difícil porque a álgebra era muito desagradável. O que eu não acho que ele considerou foi se essa álgebra estava realmente computando a coisa correta, estava fazendo com precisão e com eficiência.
Se eu fosse a pessoa mais velha na época nesse projeto, teria lido o ato de revolta. Seu orgulho o levou a usar uma solução que provavelmente era desnecessariamente complexa, sem ao menos verificar se um gradiente finito baseado em diferenças era adequado. Aposto que gastamos talvez uma semana de trabalho para executar essa otimização. No mínimo, eu o aconselharia a testar cuidadosamente o gradiente produzido. Foi preciso? Qual foi a precisão, em comparação com os derivados de diferenças finitas? De fato, existem ferramentas hoje em dia que também retornarão uma estimativa do erro em sua previsão derivada. Isso certamente é verdade para o código de diferenciação adaptável (derivest) que escrevi no MATLAB.
Teste o código. Verifique os derivados.
Mas antes de fazer QUALQUER disso, considere se outros esquemas de otimização melhores são uma opção. Por exemplo, se você estiver ajustando exponencialmente, há uma chance muito boa de poder usar mínimos quadrados não-lineares particionados (às vezes chamados de mínimos quadrados separáveis. Acho que esse foi o termo usado por Seber e Wild em seu livro.) é dividir o conjunto de parâmetros em conjuntos intrinsecamente lineares e intrinsecamente não lineares. Use uma otimização que funcione apenas nos parâmetros não lineares. Dado que esses parâmetros são "conhecidos", os parâmetros intrinsecamente lineares podem ser estimados usando mínimos quadrados lineares simples. Esse esquema reduzirá o espaço de parâmetros na otimização. Isso torna o problema mais robusto, pois você não precisa encontrar valores iniciais para os parâmetros lineares. Reduz a dimensionalidade do seu espaço de pesquisa, tornando o problema mais rápido. Mais uma vez eu forneciuma ferramenta para esse fim , mas apenas no MATLAB.
Se você usar os derivados analíticos, codifique-os para reutilizar termos. Isso pode economizar muito tempo e reduzir os bugs, economizando seu tempo. Mas então verifique esses números!
codegen
pacote, pois ele pode gerar código C ou Fortran compacto e eficiente para cada uma ou todas as expressões automaticamente.