C# библиотека для упрощения и решения алгебры

В сети есть довольно много решателей и упрощателей алгебры (например, приличный на algebra.com). Тем не менее, я ищу что-то, что можно подключить к C# в рамках более крупного проекта (я делаю свой собственный калькулятор, но, очевидно, я бы попросил разрешения и т. Д.).

В идеале я бы использовал такой код:

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

4 ответа

Мне удалось успешно позвонить в SymPy, чтобы сделать это из C#. SymPy предоставляет относительно надежную функцию упрощения, с которой у меня был хороший успех. Теперь я не совсем уверен, как правильно это упаковать (не нужно устанавливать ironpython) или даже насколько сложным может быть прямой порт кода.

  1. Установить IronPython
  2. Получить SymPy
  3. Добавьте эти ресурсы в ваш проект
    • IronPython.dll
    • IronPython.Modules.dll
    • Microsoft.Dynamic.dll
    • Microsoft.Scripting.dll
  4. C# код выглядит следующим образом:

    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"));
    

Символизм - это библиотека C#, которая реализует автоматическое упрощение алгебраических выражений.

Следуя вашему примеру выражения, следующая программа:

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)

Существует много ответов, которые можно найти в связанном вопросе SO. Хотя ни один, ни другой, кроме mathdotnet, попадают на пересечение символики (вид упрощения, о котором вы просите выше), легковесности и доступности в.Net.

Я вижу, вы уже нашли форум mathdotnet. Обратите внимание, что пара его разработчиков являются SO пользователями:

Это может дополнить поддержку, о которой вы просите.

Вы пытались создать несколько простых классов, реализующих алгоритм Shunting Yard(обратная польская запись), чем обрабатывать запись постфикса с использованием стековой обработки стека?

Другие вопросы по тегам