多项式拉格朗日反演与复合逆

膜膜膜

Tiw 永远的神!

引入

拉格朗日反演及其扩展用于求一类 F ( G ( x ) ) = H ( x ) F(G(x)) = H(x) F(G(x))=H(x) 的问题,其中 F ( x ) , H ( x ) F(x), H(x) F(x),H(x) 为已知多项式函数, G ( x ) G(x) G(x) 为待求函数。但其只能在 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间内求得 G ( x ) G(x) G(x) 的某一项系数。

拉格朗日反演

拉格朗日反演用于在 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的时间求 [ x n ] G ( x ) [x^n]G(x) [xn]G(x) [ x n ] G ( x ) [x^n]G(x) [xn]G(x) 表示 G ( x ) G(x) G(x) n n n 次项的系数,下同),其中 G ( x ) G(x) G(x) 满足 F ( G ( x ) ) = x F(G(x)) = x F(G(x))=x F ( x ) F(x) F(x) 为已知多项式,而 G ( x ) G(x) G(x) 又称为 F ( x ) F(x) F(x) 的复合逆。

有一个结论是若 F ( G ( x ) ) = x F(G(x)) = x F(G(x))=x,则 G ( F ( x ) ) = x G(F(x)) = x G(F(x))=x
感性理解是把 F ( x ) F(x) F(x) 作为 x x x 代入 F ( G ( x ) ) = x F(G(x)) = x F(G(x))=x 得到 F ( G ( F ( x ) ) ) = F ( x ) F(G(F(x))) = F(x) F(G(F(x)))=F(x),再把最外层的 F ( x ) F(x) F(x) 拆掉即可,然而这显然是 错误 的证法,因为多项式函数一般不是单调(即不是双射,没有一一对应)的。当然你也可以理解为 F ( x ) F(x) F(x) G ( x ) G(x) G(x) 互为反函数(事实上非双射的函数也没有反函数),这个结论就显然成立了。具体证法我没找到,所以就咕着吧

于是可以看出, [ x 0 ] F ( x ) = [ x 0 ] G ( x ) = 0 , [ x 1 ] F ( x ) ≠ 0 , [ x 1 ] G ( x ) ≠ 0 [x^0]F(x) = [x^0]G(x) = 0, [x^1]F(x) \neq 0, [x^1]G(x) \neq 0 [x0]F(x)=[x0]G(x)=0,[x1]F(x)=0,[x1]G(x)=0,不然最终结果不可能只剩下一个 x x x
接下来开始推导,令 G ( x ) = ∑ i = 1 n g i ⋅ x i   ( g 1 ≠ 0 ) G(x) = \sum_{i = 1}^{n} g_i \cdot x^i\ (g_1 \neq 0) G(x)=i=1ngixi (g1=0),代入 G ( F ( x ) ) = x G(F(x)) = x G(F(x))=x 得到 ∑ i = 1 n g i ⋅ F i ( x ) = x \sum_{i = 1}^{n} g_i \cdot F^i(x) = x i=1ngiFi(x)=x 两边同时求导(注意 F i ( x ) F^i(x) Fi(x) 是幂函数与多项式函数的复合函数求导)得 ∑ i = 1 n g i ⋅ i ⋅ F i − 1 ( x ) ⋅ F ′ ( x ) = 1 \sum_{i = 1}^{n} g_i \cdot i \cdot F^{i - 1}(x) \cdot F'(x) = 1 i=1ng

多项式拉格朗日插值是一种数值分析方法,在C语言中可以用于估算给定数据点上函数的近似值。它基于拉格朗日基本定理,通过构建一组特定的多项式函数L_i(x),每个函数都等于零除以除以x-x_i(x_i是数据点),当x等于某个数据点xi时,该函数的值为1。这样,多项式的乘积就可以得到一个精确表示通过数据点的函数。 C语言实现多项式拉格朗日插值的一般步骤包括: 1. 定义数据点(x坐标和y坐标数组) 2. 计算拉格朗日多项式系数 3. 根据插值公式计算给定点的值 下面是一个简单的C语言示例: ```c #include <stdio.h> float lagrange_interpolate(float x[], int n, float y[], int k) { float result = 0; for (int i = 0; i <= n; i++) { if (i != k) result = result * (x[i] - x[k]) / (x[i] - x[k]); else result = result * 1.0; // 如果i == k,则避免除以0 } return result * y[k]; } int main() { float x[] = {0, 1, 2, 3}; float y[] = {1, 4, 9, 16}; // 假设是一些平方数 int n = sizeof(x) / sizeof(x[0]); float x_val = 2.5; // 需要插值的点 printf("Interpolated value at %f is %.2f\n", x_val, lagrange_interpolate(x, n, y, find_nearest_index(x, x_val))); // 找到最近的数据点索引 return 0; } // 辅助函数找到x_val附近的最近的x数组元素的索引 int find_nearest_index(float arr[], float target) { int min_dist = INT_MAX; int index = -1; for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { int dist = abs(target - arr[i]); if (dist < min_dist) { min_dist = dist; index = i; } } return index; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值