c#解微分方程_使用C#开发符号表达库。 微分,简化,方程求解等

本文介绍了使用C#开发一个智能计算器,该计算器可以执行微分、简化和方程求解等代数运算。通过构建表达式树,实现了包括变量替代、数值和解析解法在内的功能,还支持LaTeX格式和方程求解。文章详细探讨了表达式组装、变量替换、值计算、导数计算以及方程求解的过程,旨在创建一个类似于SymPy的符号计算库。

c#解微分方程

Why does programming a calculator seem to be a task, which every beginner undertakes? History might have the answer — computers were created for this exact purpose. Unlike the beginners, we will develop a smart calculator, which, although won't reach the complexity of SymPy, will be able to perform such algebraic operations as differentiation, simplification, and equations solving, will have built-in latex support, and have implemented features such as compilation to speed up the computations.

为什么对计算器进行编程似乎是每个初学者都要完成的任务? 历史可能会给出答案-计算机就是为此目的而创建的。 与初学者不同,我们将开发一个智能计算器,该计算器虽然不会达到SymPy的复杂性,但将能够执行微分,简化和方程求解等代数运算,并具有内置的乳胶支持并具有已实现的功能(例如编译)以加快计算速度。

关于哪些文章? (What are the articles about?)

Let's do it!

我们开始做吧!

本文适用于谁? (Whom is this article for?)

对于已经看过的人 (To those who have already seen it)

first and 第一部分和 second parts. 第二部分的翻译。

表达组装 (Expression assembly)

我小时候... (When I was a child...)

什么是表情? (What is an expression?)

An expression is not a string. It is pretty obvious that a mathematical formula is either a tree or a stack, as it is shown in the example below. Each node of this tree is some kind of an operation, a variable, or a constant.

表达式不是字符串。 显而易见,数学公式可以是树,也可以是堆栈,如下面的示例所示。 该树的每个节点都是某种运算,变量或常量。

Each operation is either a function or an operator, which are actually similar to each other. Their children are the arguments of the respective functions/operators.

每个操作实际上都是彼此相似的函数或运算符。 他们的孩子是各自职能/经营者的观点。

代码中的类层次结构 (Class hierarchy in your code)

Of course, the implementation can widely vary. However, the idea is that if your tree only consists of nodes and leaves, then despite their differences from each other, they all are generalized by something. I call these «things» — entities. Therefore, the upper class will be the abstract class Entity.

当然,实现方式可以有很大的不同。 但是,这种想法是,如果树仅由节点和叶子组成,那么尽管它们彼此有所不同,但它们都被某种东西概括了。 我称这些“事物”为实体。 因此,上层类将是抽象类Entity。

抽象? (Abstract?)

And there will also be four child classes: NumberEntity, VariableEntity, OperatorEntity, FunctionEntity.

并且还将有四个子类:NumberEntity,VariableEntity,OperatorEntity,FunctionEntity。

如何构建表达式? (How to build an expression?)

We will start with building an in-code expression, i.e.

我们将从构建一个代码内表达式开始,即

var x = new VariableEntity("x");
var expr = x * x + 3 * x + 12;

If you declare an empty class VariableEntity, then such a code will throw an exception, something like «I don't know how to multiply and add.»

如果您声明一个空的类VariableEntity,则此类代码将引发异常,例如“我不知道如何相乘和相加”。

优先运算符 (Overriding Operators)

Is a very important and useful feature of most languages, it allows you to customize the execution of arithmetic operations. It is syntactically implemented differently depending on the language. For example, an implementation in C#

这是大多数语言中非常重要和有用的功能,它允许您自定义算术运算的执行。 根据语言的不同,它在语法上的实现方式也不同。 例如,在C#中的实现

public static YourClass operator +(YourClass a, YourClass b) {
    return new YourClass(a.ToString() + b.ToString());
}
Learn more about overriding statements in C# 了解有关C#中的覆盖语句的更多信息

My implementation is here.

我的实现在这里

(Ex | Im)伪型铸造 ((Ex|Im)plicit type casting)

In compilable languages like C#, such a thing is usually present and allows you to cast the type if necessary without an additional call of myvar.ToAnotherType(). So, for example, it would be more convenient to write

在像C#这样的可编译语言中,通常会出现这种情况,并允许您在必要时myvar.ToAnotherType()类型,而无需额外调用myvar.ToAnotherType() 。 因此,例如,编写起来会更方便

NumberEntity myvar = 3;

Instead of the usual

而不是通常的

NumberEntity myvar = new NumberEntity(3);
More on type casting in C# 有关C#中类型转换的更多信息

My implementation here.

我的实现在这里

悬挂式 (Hanging)

The Entity class has a Children field — this is just a list of instances of Entity, which are the arguments for this entity.

Entity类具有一个Children字段-这只是Entity实例的列表,这些实例是该实体的参数。

思想 (Thoughts)

When we call a function or operator, we should create a new entity, and put in it the children from which the function or operator is called. For example, the add operator in theory should look something like this:

当我们调用一个函数或操作符时,我们应该创建一个新实体,并在其中放入从中调用该函数或操作符的子级。 例如,理论上的add运算符应如下所示:

public static Entity operator +(Entity a, Entity b){ 
    var res = new OperatorEntity("+");
    res.Children.Add(a);
    res.Children.Add(b);
    return res;
}

That is, now if we have entity x and entity 3, then x + 3 will return the entity of the sum operator with two children: 3 and x. So, we can build expression trees.

也就是说,现在如果我们拥有实体x和实体3,则x + 3将返回具有两个子代的和运算符的实体:3和x。 因此,我们可以构建表达式树。

A function call is simpler and not as beautiful as that with an operator:

函数调用更简单,并且不如运算符那么漂亮:

public Entity Sin(Entity a)
{
    var res = new FunctionEntity("sin");
    res.Children.Add(a);
    return res;
}

My implementation is here.

我的实现在这里

Ok, we made up an expression tree.

好的,我们组成了一个表达式树。

变量替代 (Variable substitution)

Everything is extremely simple here. We have Entity — we check whether it is a variable itself; if so, we return the value, otherwise we run through the children.

这里的一切都非常简单。 我们拥有实体-我们检查它本身是否为变量; 如果是这样,则返回该值,否则我们将遍历子级。

In this «huge» 48-line file implements such a complex function.

“巨大的” 48行文件中,实现了如此复杂的功能。

价值计算 (Value calculation

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值