Библиотека С# для упрощения и решения алгебры
В Интернете существует немало алгоритмов и упростителей алгебры (например, порядочный на алгебре .com). Тем не менее, я ищу что-то, что я могу подключить к С# как часть более крупного проекта (я делаю свой собственный калькулятор, но, очевидно, я бы попросил разрешения и т.д.).
В идеале я бы использовал код вроде:
String s = MathLib.Simplify("5x*(500/x^2*(sqrt(3)/4)+1)+2x^2+(sqrt(3)/2)*x^2");
И 's' упростится до: "1082.532/x+5*x+2.866*x^2"
(точность 3dp там, но это может измениться, если нужно).
Решение для конкретной переменной тоже было бы неплохо. Мне нужно что-то легкое и быстрое слишком (расчеты, такие как выше, будут предпочтительно составлять менее 5 мс, включая задержку запуска).
После некоторых исследований такие программы, как Sage, Octave или Mathematica, вероятно, переборщит (мое приложение будет только небольшим < 200k exe, вероятно). Dotnumerics.com или Mathdotnet.com могут быть подходящими, но первый, похоже, не упоминает алгебраическое упрощение, а отсутствие документации и примеров в последнем случае отключается. Мне интересно, есть ли подходящие альтернативы. Большой список можно найти здесь:
http://en.wikipedia.org/wiki/Comparison_of_computer_algebra_systems
Ответы
Ответ 1
Мне удалось успешно позвонить в SymPy, чтобы сделать это с С#. SymPy обеспечивает относительно прочную упрощенную функцию, с которой у меня был хороший успех. Теперь я не совсем уверен, как упаковать это красиво (не нужно устанавливать ironpython), или даже насколько жестким может быть прямой порт кода.
- Установите IronPython
- Получить SymPy
- Добавьте эти ресурсы в свой проект
- IronPython.dll
- IronPython.Modules.dll
- Microsoft.Dynamic.dll
- Microsoft.Scripting.dll
-
Код С# следующим образом:
var engine = Python.CreateEngine();
var paths = engine.GetSearchPaths();
paths.Add(@"c:\program files (x86)\ironpython 2.7\lib");
paths.Add(@"c:\Development\sympy");
engine.SetSearchPaths(paths);
// expression to simplify
var expr = "0 + 1 * 1 * (x - 2) / (1 - 2) * (x - 3) / (1 - 3) * (x - 4) / (1 - 4) + 8 * 1 * (x - 1) / (2 - 1) * (x - 3) / (2 - 3) * (x - 4) / (2 - 4) + 27 * 1 * (x - 1) / (3 - 1) * (x - 2) / (3 - 2) * (x - 4) / (3 - 4) + 64 * 1 * (x - 1) / (4 - 1) * (x - 2) / (4 - 2) * (x - 3) / (4 - 3)";
var scope = engine.CreateScope();
var script = engine.CreateScriptSourceFromString(@"
from sympy import *
import clr
from System import String
expr = simplify('" + expr + @"')
result = clr.Convert(expr, String)
");
script.Execute(scope);
// prints "x**3"
Console.WriteLine(scope.GetVariable("result"));
Ответ 2
В есть вопрос о том, что есть связанный вопрос SO. Хотя никто, кроме того, что mathdotnet, падает на пересечение символики (вид упрощения, о котором вы просите выше), легкий вес, и доступность на .Net.
Я вижу вы уже нашли форум mathdotnet. Обратите внимание, что несколько его разработчиков являются пользователями SO:
Это может добавить поддержку, которую вы просите.
Ответ 3
Symbolism - это библиотека С#, которая реализует автоматическое упрощение алгебраических выражений.
Следуя вашему выражению примера, выполните следующую команду:
var x = new Symbol("x");
(5 * x * (500 / (x ^ 2) * (sqrt(3.0) / 4) + 1) + 2 * (x ^ 2) + (sqrt(3.0) / 2) * (x ^ 2))
.AlgebraicExpand()
.Disp();
отображает это на консоли:
1082.5317547305483 / x + 5 * x + 2.8660254037844384 * (x ^ 2)
Ответ 4
Попробовали ли вы создать несколько простых классов, реализующих алгоритм Shunting Yard Algorithm (обратная польская нотация), чем обрабатывать постфиксную нотацию, используя обработка стека обработка стека?