拉格朗日插值基函数导出矩阵的快速计算 
给定一组插值节点的横坐标{ x i } i = 1 n \{x_i\}_{i=1}^{n} { x i  } i = 1 n  { y i } i = 1 m \{y_i\}_{i=1}^{\red{m}} { y i  } i = 1 m  { x i } i = 1 n \{x_i\}_{i=1}^{n} { x i  } i = 1 n  n − 1 n-1 n − 1 h i ( x ) h_{i}(x) h i  ( x ) { y i } i = 1 m \{y_i\}_{i=1}^{\red{m}} { y i  } i = 1 m  L i ′ ( x ) L'_{i}(x) L i ′  ( x ) { y i } i = 1 m \{y_i\}_{i=1}^{\red{m}} { y i  } i = 1 m  H = [ h j ( y i ) ] i = 1 , m j = 1 , n \mathbb{H}=[h_{j}(y_i)]_{i=1,\red{m}}^{j=1,n} H = [ h j  ( y i  ) ] i = 1 , m j = 1 , n  D = [ h j ′ ( y i ) ] i = 1 , m j = 1 , n \mathbb{D}=[h'_{j}(y_i)]_{i=1,\red{m}}^{j=1,n} D = [ h j ′  ( y i  ) ] i = 1 , m j = 1 , n  
记 D ~ = [ h j ′ ( x i ) ] i = 1 , n j = 1 , n \widetilde{\mathbb{D}}=[h'_{j}(x_i)]_{i=1,n}^{j=1,n} D = [ h j ′  ( x i  ) ] i = 1 , n j = 1 , n  S ~ = [ h j ′ ′ ( x i ) ] i = 1 , n j = 1 , n \widetilde{\mathbb{S}}=[h''_{j}(x_i)]_{i=1,n}^{j=1,n} S = [ h j ′′  ( x i  ) ] i = 1 , n j = 1 , n  S = [ h j ′ ′ ( y i ) ] i = 1 , n j = 1 , n {\mathbb{S}}=[h''_{j}(y_i)]_{i=1,n}^{j=1,n} S = [ h j ′′  ( y i  ) ] i = 1 , n j = 1 , n  
h j ′ ( y i ) = ∑ k = 1 n h j ′ ( x k ) h k ( y i ) h'_j(y_i)=\sum_{k=1}^n h'_j(x_k) h_{k}(y_i) h j ′  ( y i  ) = ∑ k = 1 n  h j ′  ( x k  ) h k  ( y i  ) D = H ⋅ D ~ \mathbb{D}=\mathbb{H}\cdot\mathbb{\widetilde{D}} D = H ⋅ D 
 
h j ′ ′ ( x i ) = ∑ k = 1 n h j ′ ( x k ) h k ′ ( x i ) h''_j(x_i)=\sum_{k=1}^n h'_j(x_k) h'_{k}(x_i) h j ′′  ( x i  ) = ∑ k = 1 n  h j ′  ( x k  ) h k ′  ( x i  ) S ~ = D ~ 2 {\mathbb{\widetilde S}}=\mathbb{\widetilde{D}}^2 S = D 2 
 
h j ′ ′ ( y i ) = ∑ k = 1 n h j ′ ( x k ) h k ′ ( y i ) h''_j(y_i)=\sum_{k=1}^n h'_j(x_k) h'_{k}(y_i) h j ′′  ( y i  ) = ∑ k = 1 n  h j ′  ( x k  ) h k ′  ( y i  ) S = D ⋅ D ~ = H ⋅ D ~ 2 = H ⋅ S ~ \mathbb{S}=\mathbb{D}\cdot \mathbb{\widetilde{D}}=\mathbb{H}\cdot\mathbb{\widetilde{D}}^2=\mathbb{H}\cdot \mathbb{\widetilde S} S = D ⋅ D = H ⋅ D 2 = H ⋅ S 
 
...
 
h j ( n ) ( x i ) = ∑ k = 1 n h j ( n − 1 ) ( x k ) h k ′ ( x i ) h^{(n)}_j(x_i)=\sum_{k=1}^n h^{(n-1)}_j(x_k) h'_{k}(x_i) h j ( n )  ( x i  ) = ∑ k = 1 n  h j ( n − 1 )  ( x k  ) h k ′  ( x i  ) A ~ n = D ~ ⋅ A ~ n − 1 = D ~ n \mathbb{\widetilde A}_n=\mathbb{\widetilde D}\cdot {\mathbb{\widetilde A}}_{n-1}=\mathbb{\widetilde D}^n A n  = D ⋅ A n − 1  = D n 
 
h j ( n ) ( y i ) = ∑ k = 1 n h j ( n − 1 ) ( x k ) h k ′ ( y i ) h^{(n)}_j(y_i)=\sum_{k=1}^n h^{(n-1)}_j(x_k) h'_{k}(y_i) h j ( n )  ( y i  ) = ∑ k = 1 n  h j ( n − 1 )  ( x k  ) h k ′  ( y i  ) A n = D ⋅ A ~ n − 1 = H ⋅ D ~ n \mathbb{A}_n=\mathbb{ D}\cdot \widetilde{\mathbb{A}}_{n-1}=\mathbb{H}\cdot \mathbb{\widetilde D}^n A n  = D ⋅ A n − 1  = H ⋅ D n 
 
 
证明:  根据多项式插值原理, 如果f ( x ) f(x) f ( x ) [ − 1 , 1 ] [-1,1] [ − 1 , 1 ] n − 1 n-1 n − 1 
f ( x ) = ∑ k = 1 n f ( x k ) h k ( x ) , f ′ ( x ) = ∑ k = 1 n f ( x k ) h k ′ ( x ) , f(x)=\sum_{k=1}^n f(x_k) h_{k}(x), \quad  f'(x)=\sum_{k=1}^n f(x_k) h'_{k}(x), f ( x ) = k = 1 ∑ n  f ( x k  ) h k  ( x ) , f ′ ( x ) = k = 1 ∑ n  f ( x k  ) h k ′  ( x ) , 
上面左式取f = h j ′ f=h'_j f = h j ′  x = y i x=y_i x = y i  h j ′ ( y i ) = ∑ k = 1 n h j ′ ( x k ) h k ( y i ) h'_j(y_i)=\sum_{k=1}^n h'_j(x_k) h_{k}(y_i) h j ′  ( y i  ) = ∑ k = 1 n  h j ′  ( x k  ) h k  ( y i  ) 
 
上面右式取f = h j ′ f=h'_j f = h j ′  x = x i x=x_i x = x i  h j ′ ′ ( x i ) = ∑ k = 1 n h j ′ ( x k ) h k ′ ( x i ) h''_j(x_i)=\sum_{k=1}^n h'_j(x_k) h'_{k}(x_i) h j ′′  ( x i  ) = ∑ k = 1 n  h j ′  ( x k  ) h k ′  ( x i  ) 
 
上面右式取f = h j ′ f=h'_j f = h j ′  x = y i x=y_i x = y i  h j ′ ′ ( x i ) = ∑ k = 1 n h j ′ ( x k ) h k ′ ( y i ) h''_j(x_i)=\sum_{k=1}^n h'_j(x_k) h'_{k}(y_i) h j ′′  ( x i  ) = ∑ k = 1 n  h j ′  ( x k  ) h k ′  ( y i  ) 
 
...
 
 
根据该基本性质, 实际计算, 只需计算出矩阵H \mathbb{H} H D ~ \mathbb{\widetilde{D}} D 
 
定义矩阵C = [ c j k ] j = 1 , n k = 1 , n \mathbb{C}=[c_{jk}]_{j=1,n}^{k=1,n} C = [ c jk  ] j = 1 , n k = 1 , n  Z = [ z i j k ] i = 1 : m j , k = 1 : n \mathbb{Z}=[z_{ijk}]_{i=1:\red{m}}^{j,k=1:n} Z = [ z ijk  ] i = 1 : m j , k = 1 : n  
c j k = { x j − x k , j ≠ k 1 , j = k , 以及  z i j k = { y i − x k , j ≠ k 1 , j = k . c_{jk}=
\begin{cases}
  x_j-x_k, & \quad j\neq k\\
  1, & \quad j=k
\end{cases},\quad \text{以及 } 
z_{ijk} = \begin{cases}
  y_i-x_k, & \quad j\neq k\\
  1, & \quad j=k
\end{cases} . c jk  = { x j  − x k  , 1 ,  j  = k j = k  , 以及   z ijk  = { y i  − x k  , 1 ,  j  = k j = k  . 
根据公式
h j ( y i ) = ( y i − x 1 ) ( y i − x 2 ) ⋯ ( y i − x j − 1 ) ( y i − x j + 1 ) ⋯ ( y i − x n ) ( x j − x 1 ) ( x j − x 2 ) ⋯ ( x j − x j − 1 ) ( x j − x j + 1 ) ⋯ ( x j − x n ) h_j(y_i)=\dfrac{(y_i-x_1)(y_i-x_2)\cdots(y_i-x_{j-1})(y_i-x_{j+1})\cdots(y_i-x_{n})}{(x_j-x_1)(x_j-x_2)\cdots(x_j-x_{j-1})(x_j-x_{j+1})\cdots(x_j-x_{n})} h j  ( y i  ) = ( x j  − x 1  ) ( x j  − x 2  ) ⋯ ( x j  − x j − 1  ) ( x j  − x j + 1  ) ⋯ ( x j  − x n  ) ( y i  − x 1  ) ( y i  − x 2  ) ⋯ ( y i  − x j − 1  ) ( y i  − x j + 1  ) ⋯ ( y i  − x n  )  
可得
h j ( y i ) = z i j 1 z i j 2 z i j 3 ⋯ z i j n c j 1 c j 2 c j 3 ⋯ c j n h_j(y_i)=\dfrac{z_{ij1}z_{ij2}z_{ij3}\cdots z_{ijn}}{c_{j1}c_{j2}c_{j3}\cdots c_{jn}} h j  ( y i  ) = c j 1  c j 2  c j 3  ⋯ c jn  z ij 1  z ij 2  z ij 3  ⋯ z ijn   
Python的三维矩阵除以二维矩阵, 运算法则是这样的 A i j k / B j k A_{ijk}/B_{jk} A ijk  / B jk  
H = ( Z C ) 最后一个轴累乘 \mathbb{H}=\left(\dfrac{\mathbb{Z}}{\mathbb{C}}\right)_{最后一个轴累乘} H = ( C Z  ) 最后一个轴累乘  
全部Python代码如下
import  numpy as  np
class  InterpBase ( object ) : 
    def  __init__ ( self,  ip) : 
        self. ip =  np. array( ip,  float ) 
        self. c  =  np. array( [ ip] ) . T -  self. ip
        ran =  range ( len ( ip) ) 
        self. c[ ran,  ran]  =  1 
    def  valuesm ( self,  iy) : 
        z =  np. array( [ iy] ) . T -  self. ip
        n =  len ( self. ip) 
        m =  np. array( [ iy] ) . shape[ - 1 ] 
        ran =  range ( n) 
        zs =  np. zeros( ( n,  m,  n) ) 
        zs[ ran]  =  z
        zs[ ran,  : ,  ran]  =  1 
        tmp =  np. einsum( 'ijk->jik' ,  zs,  optimize= True ) 
        return  ( tmp/ self. c) . prod( axis= 2 ) 
注意: 
事实上H \mathbb{H} H 
但是都比较复杂, 对于小规模问题, 感觉没什么必要, 可点我查看参考文献 
[1] Alexander Kobe, Michael Sagralof, Fast Approximate Polynomial Multipoint Evaluation
 
[2] Justine Gauthier, Fast Multipoint Evaluation On n
 
 
根据求导公式
h j ′ ( y i ) = h j ( y i ) [ 1 y i − x 1 + 1 y i − x 2 + ⋯ + 1 y i − x j − 1 + 1 y i − x j + 1 + ⋯ 1 y i − x n ] h'_j(y_i)=h_j(y_i)\left[\frac{1}{y_i-x_1}+\frac{1}{y_i-x_2}+\cdots +\frac{1}{y_i-x_{j-1}}+\frac{1}{y_i-x_{j+1}}+\cdots \frac{1}{y_i-x_{n}}\right] h j ′  ( y i  ) = h j  ( y i  ) [ y i  − x 1  1  + y i  − x 2  1  + ⋯ + y i  − x j − 1  1  + y i  − x j + 1  1  + ⋯ y i  − x n  1  ] 
可分两种情况进行求解
y i = x i , ∀ i = 1 , 2 , ⋯ n y_i=x_i,\forall i=1,2,\cdots n y i  = x i  , ∀ i = 1 , 2 , ⋯ n m = n m=n m = n h j ′ ( y i ) = { [ 1 y i − x 1 + ⋯ + 1 y i − x j − 1 + 1 y i − x j + 1 + ⋯ 1 y i − x n ] , i = j ( y i − x 1 ) ( y i − x 2 ) ⋯ ( y i − x i − 1 ) ( y i − x i + 1 ) ⋯ ( y i − x j − 1 ) ( y i − x j + 1 ) ⋯ ( y i − x n ) ( x j − x 1 ) ( x j − x 2 ) ⋯ ( x j − x j − 1 ) ( x j − x j + 1 ) ⋯ ( x j − x n ) i ≠ j h'_j(y_i)=\begin{cases}
 \left[\frac{1}{y_i-x_1}+\cdots +\frac{1}{y_i-x_{j-1}}+\frac{1}{y_i-x_{j+1}}+\cdots \frac{1}{y_i-x_{n}}\right], & i=j\\[1em]
 \frac{(y_i-x_1)(y_i-x_2)\cdots(y_i-x_{i-1})(y_i-x_{i+1})\cdots(y_i-x_{j-1})(y_i-x_{j+1})\cdots(y_i-x_{n})}{(x_j-x_1)(x_j-x_2)\cdots(x_j-x_{j-1})(x_j-x_{j+1})\cdots(x_j-x_{n})} & i\neq j\\
\end{cases} h j ′  ( y i  ) = ⎩ ⎨ ⎧  [ y i  − x 1  1  + ⋯ + y i  − x j − 1  1  + y i  − x j + 1  1  + ⋯ y i  − x n  1  ] , ( x j  − x 1  ) ( x j  − x 2  ) ⋯ ( x j  − x j − 1  ) ( x j  − x j + 1  ) ⋯ ( x j  − x n  ) ( y i  − x 1  ) ( y i  − x 2  ) ⋯ ( y i  − x i − 1  ) ( y i  − x i + 1  ) ⋯ ( y i  − x j − 1  ) ( y i  − x j + 1  ) ⋯ ( y i  − x n  )   i = j i  = j  D ~ = [ h j ′ ( x i ) ] i = 1 : n j = 1 : n \widetilde{\mathbb{D}}=[h'_j(x_i)]_{i=1:n}^{j=1:n} D = [ h j ′  ( x i  ) ] i = 1 : n j = 1 : n  D ~ = ( R C ) 最后一个轴累乘 , 并替换对角线元素 \widetilde{\mathbb{D}}=\left(\dfrac{\mathbb{R}}{\mathbb{C}}\right)_{最后一个轴累乘, 并替换对角线元素} D = ( C R  ) 最后一个轴累乘 , 并替换对角线元素  C = [ c j k ] j = 1 , n k = 1 , n \mathbb{C}=[c_{jk}]_{j=1,n}^{k=1,n} C = [ c jk  ] j = 1 , n k = 1 , n  R = [ r i j k ] i = 1 : m j , k = 1 : n \mathbb{R}=[r_{ijk}]_{i=1:\red{m}}^{j,k=1:n} R = [ r ijk  ] i = 1 : m j , k = 1 : n  c j k = { x j − x k , j ≠ k 1 , j = k , 以及  r i j k = { x i − x k , j ≠ k 或 i 1 , j = k 或 i . c_{jk}=
\begin{cases}
 x_j-x_k, & \quad j\neq k\\
 1, & \quad j=k
\end{cases},\quad \text{以及 } 
r_{ijk} = \begin{cases}
 x_i-x_k, & \quad j\neq k 或 i\\
 1, & \quad j=k 或 i
\end{cases} . c jk  = { x j  − x k  , 1 ,  j  = k j = k  , 以及   r ijk  = { x i  − x k  , 1 ,  j  = k 或 i j = k 或 i  . 注意:  ∑ j h j ′ ( y i ) = 0 , ∀ i \sum_{j} h'_j(y_i)=0, \forall i ∑ j  h j ′  ( y i  ) = 0 , ∀ i D ~ \widetilde{\mathbb{D}} D D ~ \widetilde{\mathbb{D}} D 
 
y i = x j , ∀ , i , j y_i=x_j,\forall , i,j y i  = x j  , ∀ , i , j v \bm v v D ~ v \widetilde{\mathbb{D}}\bm v D v x \bm x x y \bm y y D v = H D ~ v \mathbb{D}\bm{v}=\mathbb{H}\widetilde{\mathbb{D}}\bm v D v = H D v D = H D ~ . \mathbb{D}=\mathbb{H}\widetilde{\mathbb{D}}. D = H D . 
 
 
快速简洁的代码
import  numpy as  np
def  interpBase ( ip,  iy,  pureComputeH= True ) : 
    c  =  np. array( [ ip] ) . T -  ip
    n =  len ( ip) 
    ran =  np. arange( n) 
    c[ ran,  ran]  =  1 
    z =  np. array( [ iy] ) . T -  ip
    zs =  np. tile( z,  ( n,  1 ,  1 ) ) 
    zs[ ran,  : ,  ran]  =  1 
    zs =  zs. transpose( ( 1 , 0 , 2 ) ) 
    abs_sort =  lambda  x:  np. sort_complex( abs ( x) +  1j * x) . imag 
    
    matrixH =  ( abs_sort( zs) / abs_sort( c) ) . prod( axis= - 1 ) 
    if  pureComputeH: 
        return  matrixH
    dzs =  np. tile( c,  ( n,  1 ,  1 ) ) 
    dzs[ ran,  : ,  ran]  =  1 
    dzs[ ran,  ran,  : ]  =  1 
    dzs =  dzs. transpose( ( 1 , 0 , 2 ) ) 
    matrixD =  ( abs_sort( dzs) / abs_sort( c) ) . prod( axis= - 1 ) 
    matrixD[ ran,  ran]  =  0 
    matrixD[ ran,  ran]  =  - matrixD. sum ( axis= - 1 ) 
    return  matrixH,  matrixH. dot( matrixD) 
abs_sort 是绝对值排序, 但是实际用起来并不能明显提高精度, 最后给出测试代码.
from  scipy import  special as  spc
deg =  60 
x,  _ =  spc. roots_jacobi( deg- 1 ,  1 ,  1 ) 
x =  np. hstack( ( [ - 1 ] ,  x,  [ 1 ] ) ) 
Lv =  spc. eval_legendre( deg,  x) 
w =  2.0 / ( deg* ( deg+ 1 ) * Lv** 2 ) 
a =  np. array( [ Lv] ) . T /  Lv
b =  np. array( [ x] ) . T -  x
ran =  np. arange( deg+ 1 ) 
a[ ran,  ran]  =  0 
b[ ran,  ran]  =  1 
D =  a/ b
D[ 0 ,  0 ]  =  -  deg* ( deg+ 1 ) / 4.0 
D[ - 1 ,  - 1 ]  =  deg* ( deg+ 1 ) / 4.0 
D3 =  interpBase( x,  x,  False ) 
err =  abs ( D -  D3[ - 1 ] ) 
print ( err. max ( ) ) 
 
如果完全硬算, 计算量太大, 而且也比较复杂. 这里提供一个矩阵向量乘积的快速算法, 也就是计算出D u \mathbb{D}\bm u D u 
先调用前面的程序计算插值多项式在w \bm w w w = { w i } i = 1 n \bm w=\{w_i\}_{i=1}^n w = { w i  } i = 1 n  x n = 1 x^n=1 x n = 1 v \bm v v 
 
进而通过iFFT得到插值多项式的系数(默认系数按升幂排列), a = iFFT  ( v ) \bm a=\operatorname{iFFT}(\bm v) a = iFFT ( v ) 
 
算出插值多项式的导数的系数 b = ( a [ 1 : ] ∗ [ 1 , 2 , ⋯   , n − 1 ] ) 追加 [ 0 ] \bm b=(\bm a[1:]*[1,2,\cdots,n-1]) 追加 [0] b = ( a [ 1 : ] ∗ [ 1 , 2 , ⋯ , n − 1 ]) 追加 [ 0 ] 
 
根据插值多项式的导数的系数, 计算出导数在w \bm w w c = FFT  ( b ) \bm c=\operatorname{FFT}(\bm b) c = FFT ( b ) 
 
最后通过w , c \bm w, \bm c w , c u \bm u u D u = H c \mathbb{D}\bm u=\mathbb{H}\bm c D u = H c 
 
 
全部Python代码如下:
class  InterpBase ( object ) : 
    def  __init__ ( self,  ip,  type = np. float ) : 
        self. ip =  np. array( ip,  type ) 
        self. c  =  np. array( [ ip] ) . T -  self. ip
        ran =  range ( len ( ip) ) 
        self. c[ ran,  ran]  =  1 
    def  valuesm ( self,  iy,  type = np. float ) : 
        z =  np. array( [ iy] ) . T -  self. ip
        n =  len ( self. ip) 
        m =  np. array( [ iy] ) . shape[ - 1 ] 
        ran =  range ( n) 
        zs =  np. zeros( ( n,  m,  n) , type ) 
        zs[ ran]  =  z
        zs[ ran,  : ,  ran]  =  1 
        tmp =  np. einsum( 'ijk->jik' ,  zs,  optimize= True ) 
        return  ( tmp/ self. c) . prod( axis= 2 ) 
def  DMatrixVectorMultiplication ( ip,  iy,  iv) : 
    
    
    n =  len ( ip) 
    ran =  np. arange( n) 
    t =  2 * np. pi/ n
    w  =  np. cos( t)  -  1j * np. sin( t) 
    w =  w** ran
    v =  InterpBase( ip) . valuesm( w,  np. complex ) . dot( iv) 
    b =  ifft( v) * ran
    c =  np. zeros_like( b) 
    c[ : - 1 ]  =  b[ 1 : ] 
    c =  fft( c) 
    return  InterpBase( w,  np. complex ) . valuesm( iy,  np. complex ) . dot( c) . real
def  DMatrix ( ip,  iy) : 
    
    
    n =  len ( ip) 
    ran =  np. arange( n) 
    t =  2 * np. pi/ n
    w  =  np. cos( t)  -  1j * np. sin( t) 
    w =  w** ran
    v =  InterpBase( ip) . valuesm( w,  np. complex ) 
    b =  ran* ifft( v. T) 
    c =  np. zeros_like( b) 
    c[ : ,  : - 1 ]  =  b[ : ,  1 : ] 
    c =  fft( c) . T
    return  InterpBase( w,  np. complex ) . valuesm( iy,  np. complex ) . dot( c) . real
注意: 
上面最后一行代码中的矩阵, 是可以事先存起来的
InterpBase(w, np.complex).valuesm(iy, np.complex)
 
InterpBase(ip)相关的系数也可以事先存起来, 它需要计算两次复矩阵乘法!
 
DMatrixVectorMultiplication与DMatrix是独立的两个函数, 它们都依赖InterpBase
 
 
同样的道理, 可以借助FFT实现多项式乘法的快速计算
例如已知f ( x ) = a 0 + a 1 x + ⋯ a n x m f(x)=a_0+a_1x+\cdots a_n x^m f ( x ) = a 0  + a 1  x + ⋯ a n  x m g ( x ) = b 0 + b 1 x + ⋯ b n x n g(x)=b_0+b_1x+\cdots b_n x^n g ( x ) = b 0  + b 1  x + ⋯ b n  x n 
求h ( x ) = f ( x ) g ( x ) = c 0 + c 1 x + ⋯ c n x m + n h(x)=f(x)g(x)=c_0+c_1x+\cdots c_n x^{m+n} h ( x ) = f ( x ) g ( x ) = c 0  + c 1  x + ⋯ c n  x m + n { c k } k = 0 m + n \{c_k\}_{k=0}^{m+n} { c k  } k = 0 m + n  
快速算法的核心思想为:
先用FFT分别算出f ( x ) , g ( x ) f(x),g(x) f ( x ) , g ( x ) m + n + 1 m+n+1 m + n + 1 
 
上步结果做乘积, 就是h ( x ) h(x) h ( x ) 
 
最后通过iFFT得到多项式h ( x ) h(x) h ( x ) 
 
 
Python 代码例如下
import  numpy as  np
from  scipy. fftpack import  fft, ifft
a =  np. array( [ 1 ,  2 ,  0 ] ) 
b =  np. array( [ 3 ,  4 ,  0 ] ) 
c =  ifft( fft( a) * fft( b) ) 
print ( c) 
a =  [ 1 ,  2 ,  3 ,  4 ] 
b =  [ 5 ,  6 ,  7 ,  8 ] 
tz =  [ 0 ] * ( len ( a) - 1 ) 
a =  np. array( a +  tz) 
b =  np. array( b +  tz) 
c =  ifft( fft( a) * fft( b) ) 
print ( c. real) 
注意: 
向量需要做适当的用0扩充
 
向量按照多项式系数升幂排列