Решатель уравнений C#

У меня есть следующее уравнение

var x = 1.0175d;
var spread = 0.0525d;
var duration = 6.36019306689938d;

var result = spread - (x / 100 - 1) / duration;

// result = 0.208128137

однако я изо всех сил пытаюсь решить уравнение для x, где мы начинаем с result.

0.0525 - ( x / 100 - 1) / 6.36019306689938 = 0.208128137

Следующий решатель уравнений возвращает правильный результат и показывает пошаговое выполнение, однако я не могу понять, как превратить это в C#, поскольку он опирается на понятие x при упрощении уравнения.

https://www.mathpapa.com/equation-solver/?q=0.0525-%28x%2F100-1%29%2F6.36019306689938%3D0.208128137

Хотите ли вы иметь «решатель» для этой конкретной формулы или вам нужно общее решение/библиотека, куда вы вставляете формулу и хотите «решить» ее для x?

Progman 25.08.2024 12:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
88
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Для символического решения уравнений вам понадобится символьный решатель, например https://symbolics.mathdotnet.com/

Вы также можете решить такие уравнения численно.

Вы можете очень легко найти корни многих уравнений с помощью алгоритма деления пополам. Проще написать это на C#. Не нужно согласовывать условия.

Вы можете переставить многие формулы (т. е. символические вычисления) с помощью переписывания ((абстрактных) систем переписывания). Возможно, это можно написать на C# и многих других языках, но f# и ocaml для этого подходят лучше.

ссылки

https://en.wikipedia.org/wiki/Bisection_method

Ответ принят как подходящий

Чтобы решить такое выражение, как spread - (x / 100 - 1) / duration = result для x, используя символы Math.NET:

Сначала используйте NuGet, чтобы добавить MathNet.Symbolics в свой проект.

Далее, чтобы решить уравнение, нужно переписать его в нормированном виде, чтобы оно было равно нулю:

spread - (x / 100 - 1) / duration - result = 0

(В этом случае мы просто вычли правую часть уравнения из обеих частей, что по определению приводит к тому, что выражение становится равным нулю.)

Затем мы можем определить выражение для решения x следующим образом:

var expression = Infix.Parse("spread - (x / 100 - 1) / duration - result").ResultValue;

Теперь нам нужно написать небольшой вспомогательный метод для решения простого корня (любезно предоставлено /u/Christoph Rüegg):

public static Expression SolveSimpleRoot(Expression variable, Expression expr)
{
    // try to bring expression into polynomial form
    Expression simple = Algebraic.Expand(Rational.Numerator(Rational.Simplify(variable, expr)));

    // extract coefficients, solve known forms of order up to 1
    Expression[] coeff = Polynomial.Coefficients(variable, simple);

    return coeff.Length switch {
        1 => Expression.Zero.Equals(coeff[0]) ? variable : Expression.Undefined,
        2 => Rational.Simplify(variable, Algebraic.Expand(-coeff[0] / coeff[1])),
        _ => Expression.Undefined
    };
}

Теперь мы можем вызвать SolveSimpleRoot(), чтобы решить выражение, а затем оценить это решение, указав все параметры spread, duration и result следующим образом:

    var solution = SolveSimpleRoot(Expression.Symbol("x"), expression);

    Dictionary<string, FloatingPoint> values = new() {
        ["spread"]   = 0.0525,
        ["duration"] = 6.36019306689938,
        ["result"]   = 0.208128137
    };

    var answer = Evaluate.Evaluate(values, solution).RealValue;

Собираем все это в полноценное консольное приложение:

using MathNet.Symbolics;

namespace Net8Console;

static class Program
{
    public static void Main()
    {
        var expression = Infix.Parse("spread - (x / 100.0 - 1.0) / duration - result").ResultValue;
        var solution   = SolveSimpleRoot(Expression.Symbol("x"), expression);

        Dictionary<string, FloatingPoint> values = new() {
            ["spread"]   = 0.0525,
            ["duration"] = 6.36019306689938,
            ["result"]   = 0.208128137
        };

        var answer = Evaluate.Evaluate(values, solution).RealValue;
        Console.WriteLine(answer);
    }

    public static Expression SolveSimpleRoot(Expression variable, Expression expr)
    {
        // try to bring expression into polynomial form
        Expression simple = Algebraic.Expand(Rational.Numerator(Rational.Simplify(variable, expr)));

        // extract coefficients, solve known forms of order up to 1
        Expression[] coeff = Polynomial.Coefficients(variable, simple);

        return coeff.Length switch {
            1 => Expression.Zero.Equals(coeff[0]) ? variable : Expression.Undefined,
            2 => Rational.Simplify(variable, Algebraic.Expand(-coeff[0] / coeff[1])),
            _ => Expression.Undefined
        };
    }
}

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