-
-
[分享]《探索现代化C++》泛读笔记摘要9
-
发表于:
2022-9-15 09:30
5346
-
《探索现代化C++》泛读笔记摘要9
Chapter 3 通用编程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class psc_f
{
public:
psc_f(double alpha) : alpha{alpha} {}
double operator() (double x) const
{
return sin(alpha * x) + cos(x);
}
private:
double alpha;
};
template <typename F, typename T>
T inline fin_diff(F f, const T& x, const T& h)
{
return (f(x + h) - f(x)) / h;
}
|
上回的求解高阶近似导数还没讲完,因为fin_diff仍然是一个三元函数。
理论上我们需要一个一元函数,于是我们根据需要定义一元仿函数来解决这个问题。
导数(Derivative)是微积分中的重要基础概念。
1 2 3 4 5 6 7 8 9 10 11 12 13 | template <typename F, typename T>
class derivative
{
public:
derivative(const F& f, const T& h) : f{f}, h{h} {}
T operator()(const T& x) const
{
return ( f(x + h) - f(x) ) / h;
}
private:
const F& f;
T h;
};
|
调用例子如下:
1 2 3 4 5 6 7 8 9 | using d_psc_f = derivative<psc_f,double>;
psc_f psc_o{ 1.0 }; / / psc_f的一个对象,sin ax + cosx 此时 a = 1.0
d_psc_f d_psc_o{psc_o, 0.001 }; / / h = 0.001
cout<< "der. of sin(x) + cos(x) at 0 is " <<d_psc_o( 0.0 )<< '\n' ;
using dd_psc_f = derivative<d_psc_f,double>;
dd_psc_f dd_psc_o{d_psc_o, 0.001 };
cout<< "2nd der. of sin(x) + cos(x) at 0 is " <<dd_psc_o( 0.0 )<< '\n' ;
|
上面的例子中为了求二阶导必须先生成了一个一阶导函数。但是如果用户只想求二阶导函数,而不希望自己生成一阶导函数的话,我们就需要直接定义二阶导函数的仿函数定义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | template<typename F,typename T>
class second_derivative
{
public:
second_derivative(const F& f, const T& h)
: h{h}, fp{f, h} {}
T operator()(const T& x) const
{
return ( fp(x + h) - fp(x) ) / h;
}
private:
T h;
derivative<F, T> fp;
};
|
调用例子
1 | second_derivative<psc_f,double> dd_psc_2_o{psc_f( 1.0 ), 0.001 };
|
如果我们希望计算3,4,5甚至是n阶导函数呢?一个个定义吗?其实可以采用递归的解法。
解法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | template <unsigned N, typename F, typename T>
class nth_derivative
{
using prev_derivative = nth_derivative<N - 1 , F, T>;
public:
nth_derivative(const F& f, const T& h)
: h{h}, fp{f, h} {}
T operator()(const T& x) const
{
return ( fp(x + h) - fp(x) ) / h;
}
private:
T h;
prev_derivative fp;
};
|
为了避免无限递归,我们需要定义一阶导数。
1 2 3 4 5 6 7 8 9 10 11 12 13 | template <typename F, typename T>
class nth_derivative < 1 , F, T>
{
public:
nth_derivative(const F& f, const T& h) : f{f}, h{h} {}
T operator()(const T& x) const
{
return ( f(x + h) - f(x) ) / h;
}
private:
const F& f;
T h;
};
|
也可使用继承写法
1 2 3 4 5 6 | template <typename F, typename T>
class nth_derivative< 1 , F, T>
: public derivative<F, T>
{
using derivative<F, T >::derivative;
};
|
现在我们就可以计算n阶导数了,比如22阶。
1 2 | nth_derivative< 22 , psc_f, double> d22_psc_o{psc_f( 1.0 ),
0.00001 };
|
未完待续。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2022-9-23 20:58
被VirtualCC编辑
,原因: 逻辑错误