C#求一阶线性微分方程的通解

发布于:2024-07-30 ⋅ 阅读:(109) ⋅ 点赞:(0)
using MathNet.Symbolics;
using System.Diagnostics;
using System.Text;

private string ConvertToLatex(string mathExpression)
{
    return mathExpression.Replace(" * ", "").Replace("*", "");
}

private string indefinite_integral(string expr)
{
    string result;
    try
    {
        // 创建新的进程信息
        ProcessStartInfo start = new ProcessStartInfo();
        start.FileName = @"python.exe";
        start.UseShellExecute = false; //不使用系统外壳程序启动
        start.RedirectStandardOutput = true; // 重定向标准输出
        start.RedirectStandardInput = true; // 重定向标准输入,
        start.CreateNoWindow = true; // 不创建新窗口
        // 启动进程,并获取相关资源
        using (Process process = Process.Start(start))
        {
            using (StreamWriter writer = process.StandardInput)
            {
                // 将 Python 代码写入标准输入流
                writer.WriteLine("import sympy");
                writer.WriteLine("from sympy import symbols, integrate");
                writer.WriteLine("x = symbols('x')");
                writer.WriteLine("e = symbols('e')");
                writer.WriteLine("f = " + expr.Replace("^","**").Replace("ln","sympy.ln"));
                writer.WriteLine("antiderivative = integrate(f, x)");
                writer.WriteLine("print(str(antiderivative).replace('**','^').replace('log','ln'))");
                writer.WriteLine("exit()");
            }
            using (StreamReader reader = process.StandardOutput)
            {
                // 读取并显示标准输出流中的内容
                result = reader.ReadToEnd().Replace("\r\n", "");
            }
        }
    }
    catch(Exception)
    {
        return "";
    }
    return result;
}

// 将函数定义为字符串
string leftExpression = "x * y' - 2 * y";
string rightExpression = "x^3";
// 将函数解析为符号表达式
SymbolicExpression leftExpr = SymbolicExpression.Parse(leftExpression.Replace("y'", "y1"));
SymbolicExpression rightExpr = SymbolicExpression.Parse(rightExpression);
// 将等式两边同时除以x
SymbolicExpression x = SymbolicExpression.Parse("x");
SymbolicExpression leftExpr2 = leftExpr / x;
SymbolicExpression px = SymbolicExpression.Parse("-2 / x");
SymbolicExpression qx = rightExpr / x;
string expr = px.ToString(); // 求解函数的不定积分
string result = indefinite_integral(expr);
SymbolicExpression px_int = SymbolicExpression.Parse(result);
// 套用对数乘方恒等式
string ln_x = "ln(x)";
bool has_ln = false;
SymbolicExpression allFactors = "1"; // 用于存储所有项目乘积
foreach (SymbolicExpression factor in px_int.Factors())
{
    if(factor.ToString() == ln_x)
    {
        has_ln = true;
    }
    else
    {
        allFactors = allFactors * factor;
    }
}
if(has_ln)
{
    px_int = SymbolicExpression.Parse("ln(x^(" + allFactors.ToString() + "))");
}
SymbolicExpression e_px_int = SymbolicExpression.Parse("e^(" + px_int.ToString() + ")");
// 用同底指数简化一个含有对数的表达式
if(e_px_int.ToString().StartsWith("e^(ln"))
{
    e_px_int = SymbolicExpression.Parse(e_px_int.ToString().Replace("e^(ln(", "").Substring(0, e_px_int.ToString().Length - 8));
}
else if(e_px_int.ToString().StartsWith("e^(-ln"))
{
    e_px_int = SymbolicExpression.Parse(e_px_int.ToString().Replace("(" + "e^(-ln(", "").Substring(0, e_px_int.ToString().Length - 9) + ")^(-1)");
}
SymbolicExpression minus_e_px_int = SymbolicExpression.Parse("e^(-1 * (" + px_int.ToString() + "))");
// 用同底指数简化一个含有对数的表达式
if(minus_e_px_int.ToString().StartsWith("e^(ln"))
{
    minus_e_px_int = SymbolicExpression.Parse(minus_e_px_int.ToString().Replace("e^(ln(", "").Substring(0, minus_e_px_int.ToString().Length - 8));
}
else if(minus_e_px_int.ToString().StartsWith("e^(-ln"))
{
    minus_e_px_int = SymbolicExpression.Parse(minus_e_px_int.ToString().Replace("(" + "e^(-ln(", "").Substring(0, minus_e_px_int.ToString().Length - 9) + ")^(-1)");
}
SymbolicExpression expression = qx * e_px_int;
expr = expression.ToString();
result = indefinite_integral(expr);
SymbolicExpression qx_e_px_int = SymbolicExpression.Parse(result);
SymbolicExpression C = SymbolicExpression.Parse("C");
SymbolicExpression finalExpression = minus_e_px_int * (qx_e_px_int + C);
SymbolicExpression finalResult = finalExpression.ExponentialSimplify();

string latexExpr0 = ConvertToLatex(leftExpression);
string latexExpr1 = ConvertToLatex(rightExpression); 
string latexExpr2 = leftExpr2.TrigonometricContract().ToLaTeX().Replace(@"\mathrm{y1}", "y'"); 
string latexExpr3 = qx.ToLaTeX();
string latexExpr4 = px.ToLaTeX();
string latexExpr5 = px_int.ToLaTeX(); 
string latexExpr6 = e_px_int.ToLaTeX(); 
string latexExpr7 = minus_e_px_int.ToLaTeX(); 
string latexExpr8 = qx_e_px_int.ToLaTeX(); 
string latexExpr9 = finalExpression.ToLaTeX(); 
string latexExpr10 = finalResult.ToLaTeX(); 

// 将通解验证结果函数和值写入Tex文件
string filePath = "first_order_linear_differential_equations_general_solution.tex"; // 文件路径
StringBuilder sb = new StringBuilder(500);

string latexHead = @"\documentclass{article}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage{CJKutf8}
\begin{document}
	\begin{CJK}{UTF8}{gkai}%正文放在此行下与\end{CJK}之间就行
";
sb.Append(latexHead);
sb.Append("\r\n");
sb.Append("    求非齐次一阶微分方程$" + latexExpr0 + " = " + latexExpr1 + "$的通解。\r\n");
sb.Append("\r\n");
sb.Append("    解:$" + latexExpr2 + " = " + latexExpr3 + "$,其中$p(x) = " + latexExpr4 + "$,$q(x) = " + latexExpr3 + "$。\r\n");
sb.Append("\r\n");
sb.Append(@"    $\int p(x) dx = " + latexExpr5 + "$\r\n");
sb.Append("\r\n");
sb.Append(@"    $e^{\int p(x) dx} = " + latexExpr6 + @"$,$e^{-\int p(x) dx} = " + latexExpr7 + "$\r\n");
sb.Append("\r\n");
sb.Append(@"    $\int q(x)e^{\int p(x) dx} dx = " + latexExpr8 + "$\r\n");
sb.Append("\r\n");
sb.Append(@"    由公式得,$y = e^{-\int p(x) dx}(\int q(x)e^{\int p(x) dx} dx + C) = " + latexExpr9 + " = " + latexExpr10 + "$。\r\n");
sb.Append("\r\n");

string latexTail = @"
	\end{CJK}
\end{document}
";
sb.Append(latexTail);

string content = sb.ToString(); // 要写入的文本内容
Encoding utf8bom = new UTF8Encoding(true);
File.WriteAllText(filePath, content, utf8bom);

first_order_linear_differential_equations_general_solution.tex文件的内容:

\documentclass{article}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage{CJKutf8}
\begin{document}
	\begin{CJK}{UTF8}{gkai}%正文放在此行下与\end{CJK}之间就行

    求非齐次一阶微分方程$xy-2y' = x^3$的通解。

    解: $-\frac{2y}{x} + y' = {x}^{2}$,其中$p(x) = -\frac{2}{x}$,$q(x) = {x}^{2}$。

    $\int p(x) dx = \ln{\frac{1}{{x}^{2}}}$

    $e^{\int p(x) dx} = \frac{1}{{x}^{2}}$,$e^{-\int p(x) dx} = {x}^{2}$

    $\int q(x)e^{\int p(x) dx} dx = x$

    由公式得,$y = e^{-\int p(x) dx}(\int q(x)e^{\int p(x) dx} dx + C) = {x}^{2}\left(C + x\right) = C{x}^{2} +{x}^{3}$。

    \end{CJK}
\end{document}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到