All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spire.math.poly.SpecialPolynomials.scala Maven / Gradle / Ivy

package spire.math.poly

import scala.annotation.tailrec
import scala.reflect.ClassTag
import scala.{specialized => spec}

import spire.algebra.{Eq, Field, Ring}
import spire.math.Polynomial
import spire.syntax.field._

object SpecialPolynomials {

  // Horner scheme polynomial generator stream
  def hornerScheme[C: Ring: Eq: ClassTag](zero: Polynomial[C], one: Polynomial[C],
                   fn: (Polynomial[C], Polynomial[C], Int) => Polynomial[C]): Stream[Polynomial[C]] = {
    def loop(pnm1: Polynomial[C], pn: Polynomial[C], n: Int = 1): Stream[Polynomial[C]] = {
      pn #:: loop(pn, fn(pn, pnm1, n), n + 1)
    }
    zero #:: loop(zero, one)
  }

  // Legendre recurrence function
  private[this] def legendreFn[C: Eq: ClassTag](implicit f: Field[C]): (Polynomial[C], Polynomial[C], Int) => Polynomial[C] =
    (pn: Polynomial[C], pnm1: Polynomial[C], n: Int) => {
      val a = Polynomial(Map((0, f.fromInt(1) / f.fromInt(n + 1))))
      val b = Polynomial(Map((1, f.fromInt(2 * n + 1))))
      val c = Polynomial(Map((0, -f.fromInt(n))))
      a * (b * pn + c * pnm1)
    }

  // Laguerre recurrence function
  private[this] def laguerreFn[C: Eq: ClassTag](implicit f: Field[C]): (Polynomial[C], Polynomial[C], Int) => Polynomial[C] =
    (pn: Polynomial[C], pnm1: Polynomial[C], n: Int) => {
      Polynomial(Map((0, f.one / f.fromInt(n + 1)))) *
      (Polynomial(Map((0, f.fromInt(2 * n + 1)), (1, -f.one))) * pn - pnm1 * Polynomial(Map((0, f.fromInt(n)))))
    }

  // Chebyshev recurrence function
  private[this] def chebyshevFn[C: Ring: Eq: ClassTag]: (Polynomial[C], Polynomial[C], Int) => Polynomial[C] =
    (pn: Polynomial[C], pnm1: Polynomial[C], n: Int) => Polynomial.twox[C] * pn - pnm1

  // Hermite recurrence function for probability
  private[this] def hermiteFnProb[C: Ring: Eq: ClassTag]: (Polynomial[C], Polynomial[C], Int) => Polynomial[C] =
    (pn: Polynomial[C], pnm1: Polynomial[C], n: Int) => Polynomial.x[C] * pn - pn.derivative

  // Hermite recurrence function for physics
  private[this] def hermiteFnPhys[C: Ring: Eq: ClassTag]: (Polynomial[C], Polynomial[C], Int) => Polynomial[C] =
    (pn: Polynomial[C], pnm1: Polynomial[C], n: Int) => Polynomial.twox[C] * pn - pn.derivative

  // Legendre polynomials of the first kind
  def legendres[C: Field: Eq: ClassTag](num: Int): Stream[Polynomial[C]] =
    hornerScheme(Polynomial.one[C], Polynomial.x[C], legendreFn[C]).take(num)

  // Laguerre polynomials
  def laguerres[C: Eq: ClassTag](num: Int)(implicit f: Field[C]): Stream[Polynomial[C]] =
    hornerScheme(Polynomial.one[C], Polynomial(Map((0, f.one), (1, -f.one))), laguerreFn[C]).take(num)

  // Chebyshev polynomials of the first kind
  def chebyshevsFirstKind[C: Ring: Eq: ClassTag](num: Int): Stream[Polynomial[C]] =
    hornerScheme(Polynomial.one[C], Polynomial.x[C], chebyshevFn[C]).take(num)

  // Chebyshev polynomials of the second kind
  def chebyshevsSecondKind[C: Ring: Eq: ClassTag](num: Int): Stream[Polynomial[C]] =
    hornerScheme(Polynomial.one[C], Polynomial.twox[C], chebyshevFn[C]).take(num)

  // Probability hermite polynomials
  def probHermites[C: Ring: Eq: ClassTag](num: Int): Stream[Polynomial[C]] =
    hornerScheme(Polynomial.one[C], Polynomial.x[C], hermiteFnProb[C]).take(num)

  // Physics hermite polynomials
  def physHermites[C: Ring: Eq: ClassTag](num: Int): Stream[Polynomial[C]] =
    hornerScheme(Polynomial.one[C], Polynomial.twox[C], hermiteFnPhys[C]).take(num)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy