#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
#define all(c) ((c).begin()), ((c).end())
#define TEST(s) if (!(s)) { cout << __LINE__ << " " << #s << endl; exit(-1); }
using Real = double;
struct Chebyshev {
static constexpr Real PI = acos(-1.0);
int n;
Real a, b;
vector<Real> c;
Chebyshev(Real a, Real b, int n) : n(n), a(a), b(b), c(n) { }
template <class F>
Chebyshev(F f, Real a, Real b, int n = 20) : n(n), a(a), b(b), c(n) {
vector<Real> h(n);
for (int k = 0; k < n; ++k) {
Real y = cos(PI*(k+0.5)/n);
h[k] = f((b-a)/2*y + (b+a)/2);
}
for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k)
c[j] += h[k] * cos(PI*j*(k+0.5)/n);
c[j] *= 2.0/n;
}
}
Real operator()(Real x) const {
Real y = (2*x - a-b)/(b-a), u = 0, v = 0;
for (int j = n-1; j >= 1; --j) {
Real w = 2*y*u - v + c[j];
v = u; u = w;
}
return y*u - v + 0.5*c[0];
}
};
Chebyshev differentiate(Chebyshev f) {
Chebyshev g = f;
g.c[f.n-2] = 2 * (f.n-1) * f.c[f.n-1];
for (int j = f.n-3; j >= 0; --j)
g.c[j] = g.c[j+2] + 2 * (j+1) * f.c[j+1];
for (int j = 0; j < g.n; ++j)
g.c[j] *= 2.0/(g.b - g.a);
return g;
}
Chebyshev integrate(Chebyshev f) {
Chebyshev g = f;
Real sum = 0, coef = (f.b-f.a)/4, sign = 1.0;
for (int j = 1; j <= g.n-2; ++j) {
g.c[j] = coef * (f.c[j-1] - f.c[j+1]) / j;
sum += sign * g.c[j];
sign = -sign;
}
g.c[f.n-1] = coef * f.c[f.n-2] / (f.n-1);
sum += sign * g.c[f.n-1];
g.c[0] = 2 * sum;
return g;
}
int main() {
Chebyshev f([](double x) { return sin(x); }, 0, 2*M_PI);
Chebyshev df = differentiate(f);
cout << fixed << setprecision(15);
cout << 2 * df(M_PI/4) << endl;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBmc3QgZmlyc3QKI2RlZmluZSBzbmQgc2Vjb25kCiNkZWZpbmUgYWxsKGMpICgoYykuYmVnaW4oKSksICgoYykuZW5kKCkpCiNkZWZpbmUgVEVTVChzKSBpZiAoIShzKSkgeyBjb3V0IDw8IF9fTElORV9fIDw8ICIgIiA8PCAjcyA8PCBlbmRsOyBleGl0KC0xKTsgfQoKdXNpbmcgUmVhbCA9IGRvdWJsZTsKc3RydWN0IENoZWJ5c2hldiB7CiAgc3RhdGljIGNvbnN0ZXhwciBSZWFsIFBJID0gYWNvcygtMS4wKTsKICBpbnQgbjsKICBSZWFsIGEsIGI7CiAgdmVjdG9yPFJlYWw+IGM7CiAgQ2hlYnlzaGV2KFJlYWwgYSwgUmVhbCBiLCBpbnQgbikgOiBuKG4pLCBhKGEpLCBiKGIpLCBjKG4pIHsgfQoKICB0ZW1wbGF0ZSA8Y2xhc3MgRj4KICBDaGVieXNoZXYoRiBmLCBSZWFsIGEsIFJlYWwgYiwgaW50IG4gPSAyMCkgOiBuKG4pLCBhKGEpLCBiKGIpLCBjKG4pIHsKICAgIHZlY3RvcjxSZWFsPiBoKG4pOwogICAgZm9yIChpbnQgayA9IDA7IGsgPCBuOyArK2spIHsKICAgICAgUmVhbCB5ID0gY29zKFBJKihrKzAuNSkvbik7CiAgICAgIGhba10gPSBmKChiLWEpLzIqeSArIChiK2EpLzIpOwogICAgfQogICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyArK2opIHsKICAgICAgZm9yIChpbnQgayA9IDA7IGsgPCBuOyArK2spCiAgICAgICAgY1tqXSArPSBoW2tdICogY29zKFBJKmoqKGsrMC41KS9uKTsKICAgICAgY1tqXSAqPSAyLjAvbjsKICAgIH0KICB9CiAgUmVhbCBvcGVyYXRvcigpKFJlYWwgeCkgY29uc3QgewogICAgUmVhbCB5ID0gKDIqeCAtIGEtYikvKGItYSksIHUgPSAwLCB2ID0gMDsKICAgIGZvciAoaW50IGogPSBuLTE7IGogPj0gMTsgLS1qKSB7CiAgICAgIFJlYWwgdyA9IDIqeSp1IC0gdiArIGNbal07CiAgICAgIHYgPSB1OyB1ID0gdzsKICAgIH0KICAgIHJldHVybiB5KnUgLSB2ICsgMC41KmNbMF07CiAgfQp9OwpDaGVieXNoZXYgZGlmZmVyZW50aWF0ZShDaGVieXNoZXYgZikgewogIENoZWJ5c2hldiBnID0gZjsKICBnLmNbZi5uLTJdID0gMiAqIChmLm4tMSkgKiBmLmNbZi5uLTFdOwogIGZvciAoaW50IGogPSBmLm4tMzsgaiA+PSAwOyAtLWopIAogICAgZy5jW2pdID0gZy5jW2orMl0gKyAyICogKGorMSkgKiBmLmNbaisxXTsKICBmb3IgKGludCBqID0gMDsgaiA8IGcubjsgKytqKQogICAgZy5jW2pdICo9IDIuMC8oZy5iIC0gZy5hKTsKICByZXR1cm4gZzsKfQpDaGVieXNoZXYgaW50ZWdyYXRlKENoZWJ5c2hldiBmKSB7CiAgQ2hlYnlzaGV2IGcgPSBmOwogIFJlYWwgc3VtID0gMCwgY29lZiA9IChmLmItZi5hKS80LCBzaWduID0gMS4wOwogIGZvciAoaW50IGogPSAxOyBqIDw9IGcubi0yOyArK2opIHsKICAgIGcuY1tqXSA9IGNvZWYgKiAoZi5jW2otMV0gLSBmLmNbaisxXSkgLyBqOwogICAgc3VtICs9IHNpZ24gKiBnLmNbal07CiAgICBzaWduID0gLXNpZ247CiAgfQogIGcuY1tmLm4tMV0gPSBjb2VmICogZi5jW2Yubi0yXSAvIChmLm4tMSk7CiAgc3VtICs9IHNpZ24gKiBnLmNbZi5uLTFdOwogIGcuY1swXSA9IDIgKiBzdW07CiAgcmV0dXJuIGc7Cn0KaW50IG1haW4oKSB7CiAgQ2hlYnlzaGV2IGYoW10oZG91YmxlIHgpIHsgcmV0dXJuIHNpbih4KTsgfSwgMCwgMipNX1BJKTsKICBDaGVieXNoZXYgZGYgPSBkaWZmZXJlbnRpYXRlKGYpOwoKICBjb3V0IDw8IGZpeGVkIDw8IHNldHByZWNpc2lvbigxNSk7CiAgY291dCA8PCAyICogZGYoTV9QSS80KSA8PCBlbmRsOwp9Cg==