计算机与代数---函数数值结果计算

0.简介

函数或者说方程,在编程语言中,直接就能通过指定变量和系数进行计算,这里主要是利用编程语言来实现这个计算。

1.方程的表示

一般来说,一个方程如\small y=x^{^{2}},在计算机中可以表示成\small y=x*x,实际的代码如下

y = x*x

当计算y的时候,给x指定值即可,如

float x = 0, y = 0;
for (int i = 0; i < 10; i++)
{
	y = x * x;
	cout << y << endl;
}

当方程更加复杂的时候。

float x = 0, y = 0;
for (int i = 0; i < 10; i++)
{
	y = x * x + 2*x;
	cout << y << endl;
}

这看起来也没什么,不过我在这里想做到的就是能直接不显示的在循环里将函数写出来,而是在循环外就已经定义好,你可能会觉得,那把方程的计算过程写在函数里,这样也可以,但是为了后面我能写函数数值求导做准备,我不打算这么做。

2.计算图表示方程

有一种东西叫做计算图,可以将计算表达式用图的方式来表达,例如表达\small y=x*x+2*x

我在写y = x*x+2*x之后,程序就会自自动生成上面的图,然后我做如下操作就会计算出x=n时候y的值。

Var x = Variable::make_var(0.0);//声明一个变量
Op y = x * x + x;//组合一个表达式
for (int i = 0; i < 10; i++)
{
	Variable::set_var(x, i);//给变量设定值
	cout << y->forward() << endl;//计算表达式
}

上面代码中有些东西我还没有叙述,但是实际上最后效果就是上面的样子。

3.实现

构建图就需要有图的结点,所以结点类如下。

class OpNode
{
public:
	virtual float forward() { return 0; }
};

目前,结点中有加法,乘法,变量,常数,所以我创建这四个基本结构。

//变量X结点
class Variable : public OpNode
{
public:
	Variable() {}
	Variable(float n):v(n) {}
	float v;
	static shared_ptr<Variable> make_var(float n) { return make_shared<Variable>(Variable(n)); }
	float forward() { return v; }
};
using Var = shared_ptr<Variable>;
//加法结点
class AddNode : public OpNode
{
public:
	AddNode(shared_ptr<OpNode> _a, shared_ptr<OpNode> _b) :a(_a), b(_b) {}
	shared_ptr<OpNode> a,b;
	float forward() { return a->forward() + b->forward(); }
};
//乘法结点
class MulNode : public OpNode
{
public:
	MulNode(shared_ptr<OpNode> _a, shared_ptr<OpNode> _b) :a(_a), b(_b) {}
	shared_ptr<OpNode> a, b;
	float forward() { return a->forward() * b->forward(); }
};
//常数结点
class Constant : public OpNode
{
public:
	float v;
	Constant() {}
	Constant(float n) :v(n) {}
	float forward() { return v; }
    static shared_ptr<Constant> make_var(float n) { return make_shared<Constant>(Constant(n)); }
};

其中forward函数主要就是计算结果的函数。有了这些结点还不够,还需要有将结点能连接在一起的函数,我以重载运算符为主。

//加法运算符重载,输入两个结点,返回加法结点
shared_ptr<AddNode> operator+(shared_ptr<OpNode> a, shared_ptr<OpNode> b)
{
	return make_shared<AddNode>(AddNode(a,b));
}
//乘法运算符重载,输入两个结点,返回乘法结点
shared_ptr<MulNode> operator*(shared_ptr<OpNode> a, shared_ptr<OpNode> b)
{
	return make_shared<MulNode>(MulNode(a, b));
}
//输入常数数和结点,返回乘法结点
shared_ptr<MulNode> operator*(float a, shared_ptr<OpNode> b)
{
	return make_shared<MulNode>(MulNode(Constant::make_var(a), b));
}
//输入结点和常数,返回乘法结点
shared_ptr<MulNode> operator*(shared_ptr<OpNode> a, float b)
{
	return make_shared<MulNode>(MulNode(a, Constant::make_var(b)));
}

有了能连接结点乘图的函数之后,将结点连接在一起。

using Op = shared_ptr<OpNode>;
Op z = x * x*x + x;

创建变量需要创建智能指针类型,设置值的时候也需要单独的函数来赋值,所以在变量类中加入了如下两个函数。

class Variable : public OpNode
{
public:
	...
    ...
	static shared_ptr<Variable> make_var(float n) { return make_shared<Variable>(Variable(n)); }
	static void set_var(shared_ptr<Variable>& a, float b){a->v = b;}
};

然后最后的总体效果如下。

int main()
{
	//声明变量
	Var x = Variable::make_var(0.0);
	Var y = Variable::make_var(0.0);
	//构建表达式
	Op z = x * x + x;
	//计算并输出结果
	for (int i = 0; i < 10; i++)
	{
		Variable::set_var(x, i);
		cout << z->forward() << endl;
	}
    return 0;
}

下一篇:导数计算

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值