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

smile.math.package.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2021 Haifeng Li. All rights reserved.
 *
 * Smile is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Smile is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Smile.  If not, see .
 */

package smile

import scala.language.implicitConversions
import smile.math.matrix._
import smile.math.special.{Beta, Erf, Gamma}
import smile.stat.distribution.{Distribution, GaussianDistribution}
import smile.stat.hypothesis.{ChiSqTest, CorTest, FTest, KSTest, TTest}

/** Mathematical and statistical functions.
  *
  * @author Haifeng Li
  */
package object math {
  implicit def pimpInt(x: Int): PimpedInt = PimpedInt(x)
  implicit def pimpDouble(x: Double): PimpedDouble = PimpedDouble(x)
  implicit def pimpIntArray(data: Array[Int]): PimpedArray[Int] = new PimpedArray[Int](data)
  implicit def pimpDoubleArray(data: Array[Double]): PimpedDoubleArray = new PimpedDoubleArray(data)
  implicit def pimpArray2D(data: Array[Array[Double]]): PimpedArray2D = new PimpedArray2D(data)

  implicit def array2Matrix(data: Array[Double]): Matrix = Matrix.column(data)
  implicit def array2Matrix(data: Array[Array[Double]]): Matrix = Matrix.of(data)
  implicit def matrixOps(matrix: Matrix): MatrixOps = new MatrixOps(matrix)

  implicit def array2VectorExpression(x: Array[Double]): VectorLift = VectorLift(x)
  implicit def vectorExpression2Array(exp: VectorExpression): Array[Double] = exp.toArray

  implicit def matrix2MatrixExpression(x: Matrix): MatrixLift = MatrixLift(x)
  implicit def matrixExpression2Array(exp: MatrixExpression): Matrix = exp.toMatrix

  def abs(x: VectorExpression): AbsVector = AbsVector(x)
  def acos(x: VectorExpression): AcosVector = AcosVector(x)
  def asin(x: VectorExpression): AsinVector = AsinVector(x)
  def atan(x: VectorExpression): AtanVector = AtanVector(x)
  def cbrt(x: VectorExpression): CbrtVector = CbrtVector(x)
  def ceil(x: VectorExpression): CeilVector = CeilVector(x)
  def exp(x: VectorExpression): ExpVector = ExpVector(x)
  def expm1(x: VectorExpression): Expm1Vector = Expm1Vector(x)
  def floor(x: VectorExpression): FloorVector = FloorVector(x)
  def log(x: VectorExpression): LogVector = LogVector(x)
  def log2(x: VectorExpression): Log2Vector = Log2Vector(x)
  def log10(x: VectorExpression): Log10Vector = Log10Vector(x)
  def log1p(x: VectorExpression): Log1pVector = Log1pVector(x)
  def round(x: VectorExpression): RoundVector = RoundVector(x)
  def sin(x: VectorExpression): SinVector = SinVector(x)
  def sqrt(x: VectorExpression): SqrtVector = SqrtVector(x)
  def tan(x: VectorExpression): TanVector = TanVector(x)
  def tanh(x: VectorExpression): TanhVector = TanhVector(x)

  def abs(x: MatrixExpression): AbsMatrix = AbsMatrix(x)
  def acos(x: MatrixExpression): AcosMatrix = AcosMatrix(x)
  def asin(x: MatrixExpression): AsinMatrix = AsinMatrix(x)
  def atan(x: MatrixExpression): AtanMatrix = AtanMatrix(x)
  def cbrt(x: MatrixExpression): CbrtMatrix = CbrtMatrix(x)
  def ceil(x: MatrixExpression): CeilMatrix = CeilMatrix(x)
  def exp(x: MatrixExpression): ExpMatrix = ExpMatrix(x)
  def expm1(x: MatrixExpression): Expm1Matrix = Expm1Matrix(x)
  def floor(x: MatrixExpression): FloorMatrix = FloorMatrix(x)
  def log(x: MatrixExpression): LogMatrix = LogMatrix(x)
  def log2(x: MatrixExpression): Log2Matrix = Log2Matrix(x)
  def log10(x: MatrixExpression): Log10Matrix = Log10Matrix(x)
  def log1p(x: MatrixExpression): Log1pMatrix = Log1pMatrix(x)
  def round(x: MatrixExpression): RoundMatrix = RoundMatrix(x)
  def sin(x: MatrixExpression): SinMatrix = SinMatrix(x)
  def sqrt(x: MatrixExpression): SqrtMatrix = SqrtMatrix(x)
  def tan(x: MatrixExpression): TanMatrix = TanMatrix(x)
  def tanh(x: MatrixExpression): TanhMatrix = TanhMatrix(x)

  /** The beta function, also called the Euler integral of the first kind.
    *
    * B(x, y) = 01 tx-1 (1-t)y-1dt
    *
    * for x, y > 0 and the integration is over [0,1].The beta function is symmetric, i.e. B(x,y) = B(y,x).
    */
  def beta(x: Double, y: Double): Double = Beta.beta(x, y)

  /** The error function (also called the Gauss error function) is a special
    * function of sigmoid shape which occurs in probability, statistics, materials
    * science, and partial differential equations. It is defined as:
    *
    * erf(x) = 0x e-t2dt
    *
    * The complementary error function, denoted erfc, is defined as erfc(x) = 1 - erf(x).
    * The error function and complementary error function are special cases of the
    * incomplete gamma function.
    */
  def erf(x: Double): Double = Erf.erf(x)

  /** The complementary error function. */
  def erfc(x: Double): Double = Erf.erfc(x)

  /** The complementary error function with fractional error everywhere less
    * than 1.2 × 10-7. This concise routine is faster than erfc.
    */
  def erfcc(x: Double): Double = Erf.erfcc(x)

  /** The inverse error function. */
  def inverf(p: Double): Double = Erf.inverf(p)

  /** The inverse complementary error function. */
  def inverfc(p: Double): Double = Erf.inverfc(p)

  /** Gamma function. Lanczos approximation (6 terms). */
  def gamma(x: Double): Double = Gamma.gamma(x)

  /** log of the Gamma function. Lanczos approximation (6 terms) */
  def lgamma(x: Double): Double = Gamma.lgamma(x)

  /** The digamma function is defined as the logarithmic derivative of the gamma function. */
  def digamma(x: Double): Double = Gamma.digamma(x)

  /** One-sample chisq test. Given the array x containing the observed numbers of events,
    * and an array prob containing the expected probabilities of events, and given
    * the number of constraints (normally one), a small value of p-value
    * indicates a significant difference between the distributions.
    */
  def chisqtest(x: Array[Int], prob: Array[Double], constraints: Int = 1): ChiSqTest = ChiSqTest.test(x, prob, constraints)

  /** Two-sample chisq test. Given the arrays x and y, containing two
    * sets of binned data, and given one constraint, a small value of
    * p-value indicates a significant difference between two distributions.
    */
  def chisqtest2(x: Array[Int], y: Array[Int], constraints: Int = 1): ChiSqTest = ChiSqTest.test(x, y, constraints)

  /** Test if the arrays x and y have significantly different variances.
    * Small values of p-value indicate that the two arrays have significantly
    * different variances.
    */
  def ftest(x: Array[Double], y: Array[Double]): FTest = FTest.test(x, y)

  /** Independent one-sample t-test whether the mean of a normally distributed
    * population has a value specified in a null hypothesis. Small values of
    * p-value indicate that the array has significantly different mean.
    */
  def ttest(x: Array[Double], mean: Double): TTest = TTest.test(x, mean)

  /** Given the paired arrays x and y, test if they have significantly
    * different means. Small values of p-value indicate that the two arrays
    * have significantly different means.
    */
  def ttest(x: Array[Double], y: Array[Double]): TTest = TTest.testPaired(x, y)

  /** Test if the arrays x and y have significantly different means.  Small
    * values of p-value indicate that the two arrays have significantly
    * different means.
    * @param equalVariance true if the data arrays are assumed to be
    *                      drawn from populations with the same true variance. Otherwise, The data
    *                      arrays are allowed to be drawn from populations with unequal variances.
    */
  def ttest2(x: Array[Double], y: Array[Double], equalVariance: Boolean = false): TTest = TTest.test(x, y, equalVariance)

  /** The one-sample KS test for the null hypothesis that the data set x
    * is drawn from the given distribution. Small values of p-value show that
    * the cumulative distribution function of x is significantly different from
    * the given distribution. The array x is modified by being sorted into
    * ascending order.
    */
  def kstest(x: Array[Double], y: Distribution): KSTest = KSTest.test(x, y)

  /** The two-sample KS test for the null hypothesis that the data sets
    * are drawn from the same distribution. Small values of p-value show that
    * the cumulative distribution function of x is significantly different from
    * that of y. The arrays x and y are modified by being sorted into
    * ascending order.
    */
  def kstest(x: Array[Double], y: Array[Double]): KSTest = KSTest.test(x, y)

  /** Pearson correlation coefficient test. */
  def pearsontest(x: Array[Double], y: Array[Double]): CorTest = CorTest.pearson(x, y)

  /** Spearman rank correlation coefficient test. The Spearman Rank Correlation
    * Coefficient is a form of the Pearson coefficient with the data converted
    * to rankings (ie. when variables are ordinal). It can be used when there
    * is non-parametric data and hence Pearson cannot be used.
    *
    * The raw scores are converted to ranks and the differences between
    * the ranks of each observation on the two variables are calculated.
    *
    * The p-value is calculated by approximation, which is good for n > 10.
    */
  def spearmantest(x: Array[Double], y: Array[Double]): CorTest = CorTest.spearman(x, y)

  /** Kendall rank correlation test. The Kendall Tau Rank Correlation
    * Coefficient is used to measure the degree of correspondence
    * between sets of rankings where the measures are not equidistant.
    * It is used with non-parametric data. The p-value is calculated by
    * approximation, which is good for n > 10.
    */
  def kendalltest(x: Array[Double], y: Array[Double]): CorTest = CorTest.kendall(x, y)

  /** Given a two-dimensional contingency table in the form of an array of
    * integers, returns Chi-square test for independence. The rows of contingency table
    * are labels by the values of one nominal variable, the columns are labels
    * by the values of the other nominal variable, and whose entries are
    * non-negative integers giving the number of observed events for each
    * combination of row and column. Continuity correction
    * will be applied when computing the test statistic for 2x2 tables: one half
    * is subtracted from all |O-E| differences. The correlation coefficient is
    * calculated as Cramer's V.
    */
  def chisqtest(table: Array[Array[Int]]): ChiSqTest = ChiSqTest.test(table)

  /** Returns an n-by-n zero matrix. */
  def zeros(n: Int) = new Matrix(n, n)
  /** Returns an m-by-n zero matrix. */
  def zeros(m: Int, n: Int) = new Matrix(m, n)
  /** Returns an n-by-n matrix of all ones. */
  def ones(n: Int) = new Matrix(n, n, 1.0)
  /** Returns an m-by-n matrix of all ones. */
  def ones(m: Int, n: Int) = new Matrix(m, n, 1.0)
  /** Returns an n-by-n identity matrix. */
  def eye(n: Int): Matrix = Matrix.eye(n)
  /** Returns an m-by-n identity matrix. */
  def eye(m: Int, n: Int): Matrix = Matrix.eye(m, n)
  /** Returns an m-by-n matrix of uniform distributed random numbers. */
  def rand(m: Int, n: Int, lo: Double = 0.0, hi: Double = 1.0): Matrix = Matrix.rand(m, n, lo, hi)
  /** Returns an m-by-n matrix of normally distributed random numbers. */
  def randn(m: Int, n: Int, mu: Double = 0.0, sigma: Double = 1.0): Matrix = Matrix.rand(m, n, new GaussianDistribution(mu, sigma))
  /** Returns the trace of matrix. */
  def trace(A: Matrix): Double = A.trace()
  /** Returns the diagonal elements of matrix. */
  def diag(A: Matrix): Array[Double] = A.diag()

  /** LU decomposition. */
  def lu(A: Array[Array[Double]]): Matrix.LU = Matrix.of(A).lu(true)
  /** LU decomposition. */
  def lu(A: Matrix): Matrix.LU = A.lu(false)
  /** LU decomposition. */
  def lu(A: MatrixExpression): Matrix.LU = A.toMatrix.lu(true)

  /** QR decomposition. */
  def qr(A: Array[Array[Double]]): Matrix.QR = Matrix.of(A).qr(true)
  /** QR decomposition. */
  def qr(A: Matrix): Matrix.QR = A.qr(false)
  /** QR decomposition. */
  def qr(A: MatrixExpression): Matrix.QR = A.toMatrix.qr(true)

  /** Cholesky decomposition. */
  def cholesky(A: Array[Array[Double]]): Matrix.Cholesky = Matrix.of(A).cholesky(true)
  /** Cholesky decomposition. */
  def cholesky(A: Matrix): Matrix.Cholesky = A.cholesky(false)
  /** Cholesky decomposition. */
  def cholesky(A: MatrixExpression): Matrix.Cholesky = A.toMatrix.cholesky(true)

  /** Returns eigen values. */
  def eig(A: Array[Array[Double]]): Matrix.EVD = Matrix.of(A).eigen(false, false, true)
  /** Returns eigen values. */
  def eig(A: Matrix): Matrix.EVD = A.eigen(false, false, false)
  /** Returns eigen values. */
  def eig(A: MatrixExpression): Matrix.EVD = A.toMatrix.eigen(false, false, true)

  /** Eigen decomposition. */
  def eigen(A: Array[Array[Double]]): Matrix.EVD = Matrix.of(A).eigen(false, true, true)
  /** Eigen decomposition. */
  def eigen(A: Matrix): Matrix.EVD = A.eigen(false, true, false)
  /** Eigen decomposition. */
  def eigen(A: MatrixExpression): Matrix.EVD = A.toMatrix.eigen(false, true, true)
  /** Returns k largest eigenvectors. */
  def eigen(A: IMatrix, k: Int): Matrix.EVD = A match {
    case a: Matrix =>
      if (a.isSymmetric) ARPACK.syev(a, ARPACK.SymmOption.LA, k)
      else ARPACK.eigen(A, ARPACK.AsymmOption.LM, k)
    case a: BandMatrix =>
      if (a.isSymmetric) ARPACK.syev(a, ARPACK.SymmOption.LA, k)
      else ARPACK.eigen(A, ARPACK.AsymmOption.LM, k)
    case a: SymmMatrix => ARPACK.syev(a, ARPACK.SymmOption.LA, k)
    case a => ARPACK.eigen(a, ARPACK.AsymmOption.LM, k)
  }

  /** SVD decomposition. */
  def svd(A: Array[Array[Double]]): Matrix.SVD = Matrix.of(A).svd(true, true)
  /** SVD decomposition. */
  def svd(A: Matrix): Matrix.SVD = A.svd(true, false)
  /** SVD decomposition. */
  def svd(A: MatrixExpression): Matrix.SVD = A.toMatrix.svd(true, true)
  /** Returns k largest singular vectors. */
  def svd(A: IMatrix, k: Int): Matrix.SVD = ARPACK.svd(A, k)

  /** Returns the determinant of matrix. */
  def det(A: Matrix): Double = lu(A).det()
  /** Returns the determinant of matrix. */
  def det(A: MatrixExpression): Double = lu(A).det()
  /** Returns the rank of matrix. */
  def rank(A: Matrix): Int = svd(A).rank()
  /** Returns the rank of matrix. */
  def rank(A: MatrixExpression): Int = svd(A).rank()
  /** Returns the inverse of matrix. */
  def inv(A: Matrix): Matrix = A.inverse()
  /** Returns the inverse of matrix. */
  def inv(A: MatrixExpression): Matrix = A.toMatrix.inverse()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy