首页
社区
课程
招聘
[分享]《探索现代化C++》泛读笔记摘要10
2022-9-16 07:09 4985

[分享]《探索现代化C++》泛读笔记摘要10

2022-9-16 07:09
4985

《探索现代化C++》泛读笔记摘要10

Chapter 3 通用编程

仿函数

上回写出来的n阶导数,近似度仍然太低。

 

从泰勒级数中,我们知道,当后向差分被应用于前向差分时。其误差从O(h)减少到O(h^2)。
也就是说,我们可以通过交替使用前向差分和后向差分来提高近似度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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>
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;
};
 
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 N & 1 ? (fp(x + h) - fp(x)) / h
            : (fp(x) - fp(x - h)) / h;
    }
private:
    T h;
    prev_derivative fp;
};
 
template <typename F, typename T>
class nth_derivative<1, F, T>
    : public derivative<F, T>
{
    using derivative<F, T >::derivative;
};
 
int main()
{
    nth_derivative<22, psc_f, double> d22_psc_o{ psc_f(1.0),0.00001 };
    cout << "22nd der. of sin(x) + cos(x) at 0 is " << d22_psc_o(0.0)
       << '\n';
}

但是最后作者指出这个计算方式也不尽如人意。通过在每个位置只计算一次f,并以适当的二项式系数对其进行缩放,可以将计算工作量从指数级降低到线性。希望你的教授不会看到这篇文章而成为下一个编程练习题的灵感。由此可见即使是最酷的编程也不能代替坚实的数学。

 

读者我只能说做一个数学家好费脑!

 

Oh! 天呐,这一小节的跳过吧!

通用推导

接下来介绍了一个二元仿函数的应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template <typename Iter , typename T , typename BinaryFunction>
T accumulate(Iter it , Iter end , T init , BinaryFunction op)
{
    for (; it != end; ++it)
            init= op(init, *it);
    return init;
}
 
template <typename T>
struct add
{
    T operator()(const T& x, const T& y) const {
        return x + y;
    }
};
 
struct times
{
    template <typename T>
    T operator()(const T& x, const T& y) const {
        return x * y;
    }
};
 
vector v= {7.0, 8.0, 11.0};
double s= accumulate(v.begin(), v.end(), 0.0, add<double>{}); // 计算和
double p= accumulate(v.begin(), v.end(), 1.0, times{}); // 计算乘积

舒了口气,上面这个代码阅读难度一下子降低了。


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2022-9-17 08:00 被VirtualCC编辑 ,原因: 章节错误
收藏
点赞0
打赏
分享
最新回复 (4)
雪    币: 6
活跃值: (2985)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
咖啡_741298 2022-9-17 17:17
2
0
double s= accumulate(v.begin(), v.end(), 0.0, add<double>{})
这句里面的  add<double>{}  没参数吗?
雪    币: 4195
活跃值: (5634)
能力值: ( LV7,RANK:116 )
在线值:
发帖
回帖
粉丝
VirtualCC 2022-9-21 08:04
3
0
咖啡_741298 double s= accumulate(v.begin(), v.end(), 0.0, add{}) 这句里面的 add{} 没参数吗?
雪    币: 8104
活跃值: (4391)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sunsjw 1 2022-9-24 11:19
4
0
你这里是求sin+cos的22阶导数,那如果我想要求任意函数的任意阶导数有没有办法?
雪    币: 4195
活跃值: (5634)
能力值: ( LV7,RANK:116 )
在线值:
发帖
回帖
粉丝
VirtualCC 2022-9-24 23:00
5
0
sunsjw 你这里是求sin+cos的22阶导数,那如果我想要求任意函数的任意阶导数有没有办法?
你得自己写一个类似psc_f的函数出来,实例化模板nth_derivative类。如果你真要解一些导数,还是推荐你用matlab吧,作者在这里也就演示一下c++文法。
游客
登录 | 注册 方可回帖
返回