Я работаю над некоторым заданием по численному анализу, где я должен оценивать, строить и дифференцировать математические выражения. Среди прочего Я реализовал деревья выражений с Java .
Пока что я могу построить дерево выражений, отобразить его с помощью Latex, оценить его, построить его и получить его производную. Интерфейс, который реализуется составными функциями в дереве, имеет следующие методы:
Function[] child();<br>
void addChild(Function chld);<br>
double evaluate(HashMap subMap);<br>
String toLatex();<br>
int precedence();<br>
Function derivative();
Реализации, которые я до сих пор кодировал: Constant, Variable, Add, Subtract, Multiply, Divide, Power, Sine, Cosine, Ln
.
Теперь, когда я различаю некоторую базовую функцию, я получаю ее в неприведенной форме:
d/dx(x^2) ===> x^2 * (1 * 2 / x + 0 * ln(x))
Это потому, что производная реализована в наиболее общем виде.
Решение, о котором я подумал, заключается в том, что при построении каждого узла f
в дереве с учетом дочерних элементов f
я рекурсивно сокращаю дочерние элементы, а затем выполняю некоторую наивную реконструкцию. После такой реконструкции дети «вместе» сокращаются по отношению к f
.
Например, учитывая выражение 0 * x, дерево должно выглядеть так:
*
/ \
0 x
При построении узла *, если один из его дочерних элементов является нулевой константой, узел * становится нулевой константой. И конечно выбрасывает своих детей.
0
И так далее для всех различных случаев умножения.
Это требует тщательного анализа от моего имени и может не охватывать все случаи - учитывая, что умножение - не единственная необходимая функция.
Задача: с учетом дерева выражений, как я могу сделать базовое сокращение для него? Если бы вы могли отослать меня к любым ссылкам или документам, которые представляют решение для этой проблемы - предпочтительно в элегантном OO way - или, если бы вы взялись за это раньше, ваша помощь будет действительно признательна.