парсинг — анализируемая символьная дифференциация в переполнении стека

Я нашел эти две библиотеки:
— Мупарсер
— symbolicc ++

Первый способен эффективно разбирать математические выражения, чтобы с минимальным переносом я мог создать объект парсера, чтобы

parser my_parser("1/2 * x^2");
cout<<myparser(2)<<endl;

Это привело бы к печати 2.0. Это замечательно, но работает только с двойниками, верно?

Второй реализует объект Symbolic, так что в примере я могу сделать что-то вроде:

Symbolic x("x");
Symbolic x2 = x^2;
cout<<df(x2, x)<<endl;

В результате 2.0 * х. Так что он способен различать выражения, и это нормально.

Что мне нужно сделать, это сочетание двух! Мне нужно, чтобы функция была проанализирована, а затем дифференцирована, чтобы я мог сделать что-то вроде:

 cout<<df("1/2 * x^2", "x")<<endl;

И я хотел бы, чтобы он также распечатал 2.0 * x.

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

Так есть ли другой обходной путь? Мне нужно что-то, что принимает входную строку с выражением и возвращает выходную строку с производной этого выражения.

Спасибо!

0

Решение

Это не полный отвечу, так как, как говорится, TMTOWTDI. Однако, чтобы иметь возможность использовать Symbolic ++, вам нужно иметь доступ на уровне программы… то есть вы не можете писать и компилировать

Symbolic x("x");
Symbolic x2 = x^2;

но нужно что-то порядка (но waaaaay более гибкий, чем)

if (there_is_x_symbol) {
expr = Symbolic x("x");
}
if (raise_to_the_2nd_power) {
expr = expr^2;
}

Чтобы сделать это органично, вы необходимость парсер и парсер, который не просто экспортирует evaluate() метод, но то, что позволит вам получить доступ к дереву выражений, например

     ( multiply )
/        \
( 2 )       ( square )
\
( x )

Это вы можете оценить рекурсивно:

left = myEvaluate(node.left)
right = myEvaluate(node.right)
if (node.op == multiply) {
return left * right;
}
if (node.op == square ) {
return right ^ 2;
}
...

Библиотеки muparser (и muparserX), похоже, не позволяют этого.

Есть несколько других алгебраических парсеров, например этот выглядит многообещающе Вы можете использовать алгоритм Parser поставщика и написать собственный оценщик, который использует Symbolic ++ и выводит выражение Symbolic ++.

Вам не нужны глубокие знания грамматики, чтобы взломать такой парсер — большинство просто сгенерирует Обратная польская запись стек, и это все, что вам действительно нужно знать.

В Бокка Аль Лупо 🙂

0

Другие решения


По вопросам рекламы [email protected]