二阶切比雪夫多项式实现(scala版、python版)

22 篇文章 0 订阅
21 篇文章 0 订阅

一维二阶切比雪夫多项式和二维二阶切比雪夫多项式

scala版参考:

http://hxfcalf.blog.163.com/blog/static/21575548201373124214412

http://hxfcalf.blog.163.com/blog/static/21575548201373152715780

何老师的版本中的问题是采用了Float作为数据的存储类型,但是由于Float的精度不够,导致二维二阶切比雪夫多项式结果不能收敛,

所以通过将数据类型修改为BigDecimal的方式解决了这个问题。

一维二阶切比雪夫多项式:

package chebList
import tools.BigDecimalTools
/**
 * 一维2阶切比雪夫多项式
 * gao
 * 2015-08-04
 */

case class CbVal(I0: Int) {
  val K0 = 2
  //二阶切比雪夫多项式系数
  val cb = new Array[Seq[BigDecimal]](K0 + 1)
  for (k <- 0 to K0) cb(k) = k match{
    case 0 => (1 to I0).map (x => BigDecimal.decimal(1.0))
    case 1 => (1 to I0) map (x => BigDecimal.decimal(x - (I0 + 1.0) / 2.0))
    case 2 => cb(1) map (x => x * x - (I0 * I0 - 1) / (4 * (4 - 1)))
  }

  //标准化处理后的二阶切比雪夫多项式系数
  val v = new Array[Seq[BigDecimal]](K0 + 1)
  def sq(v: Seq[BigDecimal]):BigDecimal = {
    BigDecimalTools.bigSqrt(v.map(x => x * x).sum)
  }
  for (k <- (0 to K0).par) {
    v(k) = cb(k).map(x => x / sq(cb(k)))
  }
}

class D1Cheb(f: Array[BigDecimal]) extends CbVal(f.length) {
  //一维要素的多项式权重
  val A = new Array[BigDecimal](K0 + 1)
  for (k <- (0 to K0).par) {
    A(k)= v(k).zip(f).map(x => x._1 * x._2).sum
  }
  //一维要素拟合
  val fit = new Array[BigDecimal](f.length)
  for (i <- (0 until f.length).par){
    fit(i) = Seq(v(0)(i),v(1)(i),v(K0)(i)).zip(A).map(x => x._1 * x._2).sum
  }
  //一维要素拟合
  def invers(len: Int, AA : Array[BigDecimal]):Array[BigDecimal]={
    val xx = new CbVal(len)
    val ffit = new Array[BigDecimal](len)
    for (i <- (0 until len).par){
      ffit(i) = Seq(xx.v(0)(i),xx.v(1)(i),xx.v(K0)(i)).zip(AA).map(x => x._1 * x._2).sum
    }
    ffit
  }
}

object CbVal extends App {
//  val c = CbVal(5)
//
//  for (k <- (0 to c.K0)) {
//    println(c.cb(k))
//  }
//  for (k <- (0 to c.K0)) {
//    println(c.v(k))
//  }

  val data: Array[BigDecimal] = Array(0.0, 0.9999997, 2, 3.0, 4.0)
  val result:Array[BigDecimal] = Array(0.0,1.8,2.0,3.0,4.0)
  for(i <- (0 until 100)) {
    val curData = result
    val cc = new D1Cheb(curData)
    val curResult = cc.fit
    result(1) = curResult(1)
    println(i,result(1))
  }
}
二维二阶切比雪夫多项式:

package chebList

/**
 * 二维2阶切比雪夫多项式
 * gao
 * 2015-08-04
 */
import Array._
case class D2Cheb(f: Array[Array[BigDecimal]]) {
  val x = CbVal(f(0).length)
  val y = CbVal(f.length)
  //二维要素的多项式权重
  val A = Array.fill(y.K0 + 1, x.K0 + 1)(BigDecimal.decimal(0.0))
  for (
    k <- (0 to y.K0); s <- (0 to x.K0);
    i <- (0 until y.I0); j <- (0 until x.I0)
  ) {
    A(k)(s) += f(i)(j) * y.v(k)(i) * x.v(s)(j)
  }

  //二维要素拟合
  val fit = Array.fill(y.I0, x.I0)(BigDecimal.decimal(0.0))
  for (
    i <- (0 until y.I0); j <- (0 until x.I0);
    k <- (0 to y.K0); s <- (0 to x.K0)
  ) {
    fit(i)(j) += A(k)(s) * y.v(k)(i) * x.v(s)(j)
  }

  //二维要素拟合
  def inverse(cols: Int, rows: Int, AA: Array[Array[BigDecimal]]): Array[Array[BigDecimal]] = {
    val xx = CbVal(cols)
    val yy = CbVal(rows)
    val z = ofDim[BigDecimal](yy.I0, xx.I0)
    for (
      i <- (0 until yy.I0).par; j <- (0 until xx.I0).par;
      k <- (0 to yy.K0).par; s <- (0 to xx.K0).par
    ) {
      z(i)(j) += AA(k)(s) * yy.v(k)(i) * xx.v(s)(j)
    }
    z
  }
}

object D2Cheb extends App {
  val data: Array[Array[BigDecimal]] = Array(Array(0.0,1.0,2.0,3.0,4.0),
          Array(1.0,2.6,3.0,4.0,5.0),
          Array(2.0,3.0,4.0,5.0,6.0),
          Array(3.0,4.0,5.0,6.0,7.0),
          Array(4.0,5.0,6.0,7.0,8.0))

  for(i <- (0 until 100)){
    val curData = data
    val cc = new D2Cheb(data)
    val curFit = cc.fit
    data(1)(1) = curFit(1)(1)
    println(i+", "+data(1)(1))
  }
}

python版本是基于scala版本进行改进的,能够很好的收敛:

# -*- coding: utf-8 -*-
__author__ = 'Administrator'
'''
chebPolynomial
reference 周家斌,不规则格点上的车贝雪夫多项式展开问题 大气科学 1983
'''

import numpy as np
import math

##二阶切比雪夫多项式系数
def CbVal(IO):
    KO = 2
    ##二阶切比雪夫多项式系数
    cb = np.zeros([KO+1, IO])
    cb[0] = 1.0
    cb1err = (IO+1.0)/2.0
    cb[1] = [i-cb1err+1 for i in range(5)]
    cb2err = (IO*IO-1.0)/12.0
    cb[2] = [i*i-cb2err for i in cb[1]]

    ##标准化处理后的二阶切比雪夫多项式系数
    v = np.zeros([KO+1, IO])
    sq0 = sq(cb[0])
    v[0] = [i/sq0 for i in cb[0]]
    sq1 = sq(cb[1])
    v[1] = [i/sq1 for i in cb[1]]
    sq2 = sq(cb[2])
    v[2] = [i/sq2 for i in cb[2]]
    return KO,cb,v

##求平方和的根
def sq(v):
    return math.sqrt(sum([i*i for i in v]))

##一维二阶切比雪夫多项式
def D1Cheb(f):
    dimension = len(f)
    KO,cb,v = CbVal(dimension)

    A = np.zeros([KO+1])
    A[0] = sum(i[0]*i[1] for i in zip(f,v[0]))
    A[1] = sum(i[0]*i[1] for i in zip(f,v[1]))
    A[2] = sum(i[0]*i[1] for i in zip(f,v[2]))

    fit = np.zeros([dimension])
    for i in range(dimension):
        fit[i] = sum(i[0]*i[1] for i in zip([v[0][i],v[1][i],v[2][i]],A))
    return fit

##二维二阶切比雪夫多项式
def D2Cheb(f):
    dimensionX = len(f[0])
    dimensionY = len(f)

    KOX,cbX,vX = CbVal(len(f[0]))
    KOY,cbY,vY = CbVal(len(f))

    ##二维要素的多项式权重
    A = np.zeros([KOY+1, KOX+1])

    for k in range(KOY+1):
        for s in range(KOX+1):
            for i in range(dimensionY):
                for j in range(dimensionX):
                    A[k][s] += f[i][j] * vY[k][i] * vX[s][j]

    ##二维要素拟合
    fit = np.zeros([dimensionY, dimensionX])
    for i in range(dimensionY):
        for j in range(dimensionX):
            for k in range(KOY+1):
                for s in range(KOX+1):
                    fit[i][j] += A[k][s] * vY[k][i] * vX[s][j]

    return fit

if __name__ == "__main__":
    # cb,v = CbVal(5)
    # print cb
    # print v
    data = [[0.0, 1.0, 2.0, 3.0, 4.0],
            [1.0, 2.6, 3.0, 4.0, 5.0],
            [2.0, 3.0, 4.0, 5.0, 6.0],
            [3.0, 4.0, 5.0, 6.0, 7.0],
            [4.0, 5.0, 6.0, 7.0, 8.0]]

    fit = D2Cheb(data)

    for i in range(100):
        curData = data
        curFit = D2Cheb(curData)
        data[1][1] = curFit[1][1]
        print i, data[1][1]

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
比雪夫多项式和雅可比多项式都是常见的正交多项式。其中,比雪夫多项式是定义在区间[-1,1]上的正交多项式,而雅可比多项式则是定义在区间[-1,1]上的一类正交多项式。两者都在数学和工程学科中有广泛的应用。 关于比雪夫多项式,可以进一步了解以下内容: - 比雪夫多项式是一类特殊的多项式,其定义为Tn(x) = cos(n * arccos(x)),其中n为多项式的次数,x为自变量。第一类比雪夫多项式在数学和物理学中有广泛的应用,例如在逼近论、微分方程、傅里叶级数等领域。 - 比雪夫多项式的性质包括正交性、归一性、三项递推关系等。其中,正交性是指在区间[-1,1]上,不同次数的比雪夫多项式之间的内积为0,相同次数的比雪夫多项式之间的内积为一个常数。 - 比雪夫多项式的应用包括多项式插值、函数逼近、数值积分等。其中,多项式插值是指利用比雪夫多项式在给定区间上的节点进行插值,得到一个多项式函数,用于逼近原函数。 关于雅可比多项式,可以进一步了解以下内容: - 雅可比多项式是定义在区间[-1,1]上的一类正交多项式,其定义为P^(α,β)_n(x),其中α和β为两个参数,n为多项式的次数,x为自变量。不同的参数α和β会导致不同的雅可比多项式。 - 雅可比多项式的性质包括正交性、归一性、三项递推关系等。其中,正交性是指在区间[-1,1]上,不同次数的雅可比多项式之间的内积为0,相同次数的雅可比多项式之间的内积为一个常数。 - 雅可比多项式的应用包括多项式插值、函数逼近、数值积分等。其中,多项式插值是指利用雅可比多项式在给定区间上的节点进行插值,得到一个多项式函数,用于逼近原函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值