BLAS.java

package org.mklab.sdpj.gpack.blaswrap;

import org.mklab.nfc.matrix.ComplexNumericalMatrix;
import org.mklab.nfc.matrix.DoubleComplexMatrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.RealNumericalMatrix;
import org.mklab.nfc.scalar.ComplexNumericalScalar;
import org.mklab.nfc.scalar.DoubleComplexNumber;
import org.mklab.nfc.scalar.DoubleNumber;
import org.mklab.nfc.scalar.RealNumericalScalar;


/**
 * @author koga
 * @version $Revision$, 2009/04/24
 */
public class BLAS {

  /** */
  private final static int threadableMatrixSize = 2500;
  /** */
  private final static int threadableVectorSize = 50;
  /** */
  private final static boolean CREATE_THREAD = false;

  /**
   * dy= dy+da.*dx
   * <p>
   * 引数dyの値は変更されます。
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param da da
   * @param dx dx
   * @param incx incx
   * @param dy dy
   * @param incy incy
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> void daxpy(int n, RS da, RS[] dx, int incx, RS[] dy, int incy) {
    new Daxpy<RS,RM,CS,CM>().daxpy(n, da, dx, incx, dy, incy);
  }

  /**
   * dy= dy+dx
   * <p>
   * 引数dyの値は変更されます。
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param dx dx
   * @param incx incx
   * @param dy dy
   * @param incy incy
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> void dxpy(int n, RS[] dx, int incx, RS[] dy, int incy) {
    new Dxpy<RS,RM,CS,CM>().dxpy(n, dx, incx, dy, incy);
  }

  /**
   * dy= dy-dx
   * <p>
   * 引数dyの値は変更されます。
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param dx dx
   * @param incx incx
   * @param dy dy
   * @param incy incy
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> void dxmy(int n, RS[] dx, int incx, RS[] dy, int incy) {
    new Dxmy<RS,RM,CS,CM>().dxmy(n, dx, incx, dy, incy);
  }

  /**
   * 配列dxをdyにコピーします。
   * <p>
   * 配列は参照渡しなので、このメソッドを呼び出した後のdyは、 dxをコピーしたものとなります。
   * 
   * @param n n
   * @param dx dx
   * @param incx incx
   * @param dy dy
   * @param incy incy
   */
  public static void dcopy(int n, double[] dx, int incx, double[] dy, int incy) {
    new Dcopy<DoubleNumber,DoubleMatrix,DoubleComplexNumber,DoubleComplexMatrix>().dcopy(n, dx, incx, dy, incy);
  }

  /**
   * dxをdyへコピーします。
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param dx dx
   * @param incx incx
   * @param dy dy
   * @param incy incy
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> void dcopy(int n, RS[] dx, int incx, RS[] dy, int incy) {
    new Dcopy<RS,RM,CS,CM>().dcopy(n, dx, incx, dy, incy);
  }

  /**
   * dot product(内積)の計算を行います。
   * <p>
   * 引数で与えたパラメータ(配列等)は変更されません
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param dx dx
   * @param incx incx
   * @param dy dy
   * @param incy incy
   * @return reuslt
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> RS ddot(int n, RS[] dx, int incx, RS[] dy, int incy) {
    return new Ddot<RS,RM,CS,CM>().ddot(n, dx, incx, dy, incy);
  }

  /**
   * C := alpha*op(A)*op(B)+beta*C
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param transa transa
   * @param transb transb
   * @param m op(A)とCの列数
   * @param n op(B)とCの行数
   * @param k op(A)の行数と op(B)の列数
   * @param alpha alpha
   * @param a a
   * @param lda transa = 'n' then max(1,m),otherwise max(1,k)
   * @param b b
   * @param ldb transb = 'n' then max(1,k), otherwise max(1,n)
   * @param beta beta
   * @param c c
   * @param ldc max(1,m)
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dgemm(String transa, String transb, int m, int n, int k, RS alpha, RS[] a, int lda, RS[] b, int ldb, RS beta, RS[] c, int ldc) {
    if (n * m > threadableMatrixSize && CREATE_THREAD) {
      return new DgemmThread<RS,RM,CS,CM>().dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
    }

    return new Dgemm<RS,RM,CS,CM>().dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
  }

  /**
   * y=alpha*a*x+beta*y or y=alpha*a'*x+beta*y
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param trans unchanged
   * @param m unchanged Aの行数
   * @param n unchanged Aの列数
   * @param alpha unchanged
   * @param a unchanged matrix A
   * @param lda unchanged
   * @param x unchanged vector X
   * @param incx unchanged
   * @param beta unchanged
   * @param y is overwritten by the update vector y
   * @param incy unchanged
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dgemv(String trans, int m, int n, RS alpha, RS[] a, int lda, RS[] x, int incx, RS beta, RS[] y, int incy) {
    return new Dgemv<RS,RM,CS,CM>().execute(trans, m, n, alpha, a, lda, x, incx, beta, y, incy);
  }

  /**
   * dx=da*dx ベクトルのスケールを求めます
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param da da
   * @param dx dx
   * @param incx incx
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> void dscal(int n, RS da, RS[] dx, int incx) {
    new Dscal<RS,RM,CS,CM>().execute(n, da, dx, incx);
  }

  /**
   * C := alpha*A*A' + beta*C, or C := alpha*A'*A + beta*C,
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param uplo uplo
   * @param trans trans
   * @param n n
   * @param k k
   * @param alpha alpha
   * @param a a
   * @param lda lda
   * @param beta beta
   * @param c c
   * @param ldc ldc
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dsyrk(String uplo, String trans, int n, int k, RS alpha, RS[] a, int lda, RS beta, RS[] c, int ldc) {
    return new Dsyrk<RS,RM,CS,CM>().execute(uplo, trans, n, k, alpha, a, lda, beta, c, ldc);
  }

  /**
   * op( A )*X = alpha*B, or X*op( A ) = alpha*B,
   * 
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param side left or right
   * @param uplo upper or lower
   * @param transa transpose or no transpose
   * @param diag A is unit triangular or not unit triangular
   * @param m m
   * @param n n
   * @param alpha scalar
   * @param a matrix
   * @param lda lda
   * @param b m by n Matrix. overwritten by transformed matrix
   * @param ldb ldb
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dtrsm(String side, String uplo, String transa, String diag, int m, int n, RS alpha, RS[] a, int lda, RS[] b, int ldb) {
    return new Dtrsm<RS,RM,CS,CM>().execute(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param side side
   * @param uplo uplo
   * @param transa transa
   * @param diag diag
   * @param m m
   * @param n n
   * @param alpha alpha
   * @param a a
   * @param lda lda
   * @param b overwritten
   * @param ldb ldb
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dtrmm(String side, String uplo, String transa, String diag, int m, int n, RS alpha, RS[] a, int lda, RS[] b, int ldb) {
    return new Dtrmm<RS,RM,CS,CM>().execute(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param uplo unchanged
   * @param trans unchanged
   * @param diag unchanged
   * @param n unchanged
   * @param a unchanged
   * @param lda unchanged
   * @param x is overwritten with the transformed vector x
   * @param incx unchanged
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dtrmv(String uplo, String trans, String diag, int n, RS[] a, int lda, RS[] x, int incx) {
    return new Dtrmv<RS,RM,CS,CM>().execute(uplo, trans, diag, n, a, lda, x, incx);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param uplo uplo
   * @param trans trans
   * @param diag diag
   * @param n n
   * @param a a
   * @param lda lda
   * @param x x
   * @param incx incx
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dtrsv(String uplo, String trans, String diag, int n, RS[] a, int lda, RS[] x, int incx) {
    return new Dtrsv<RS,RM,CS,CM>().execute(uplo, trans, diag, n, a, lda, x, incx);
  }

  /**
   * 与えられた文字列が大文字小文字に関係なく等しければtrue 文字列s1が文字列s2から始まっていた場合でもtrue
   * 
   * @param s1 s1
   * @param s2 s2
   * @return result
   */
  public static boolean lsame(String s1, String s2) {
    return (s1.toLowerCase()).equals(s2.toLowerCase()) || (s1.toLowerCase()).startsWith(s2.toLowerCase());
  }

  /**
   * パラメータのエラーを検出する。 エラーがあると停止
   * 
   * @param srname srname
   * @param info info
   * @return result
   */
  public static int xerbla(String srname, int info) {
    return new Xerbla().execute(srname, info);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param m m
   * @param n n
   * @param alpha alpha
   * @param x x
   * @param incx incx
   * @param y y
   * @param incy incy
   * @param a a
   * @param lda lda
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dger(int m, int n, RS alpha, RS[] x, int incx, RS[] y, int incy, RS[] a, int lda) {
    return new Dger<RS,RM,CS,CM>().execute(m, n, alpha, x, incx, y, incy, a, lda);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param uplo uplo
   * @param trans trans
   * @param n n
   * @param k k
   * @param alpha alpha
   * @param a a
   * @param lda lda
   * @param b b
   * @param ldb ldb
   * @param beta beta
   * @param c c
   * @param ldc ldc
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dsyr2k(String uplo, String trans, int n, int k, RS alpha, RS[] a, int lda, RS[] b, int ldb, RS beta, RS[] c, int ldc) {
    return new Dsyr2k<RS,RM,CS,CM>().execute(uplo, trans, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param dx dx
   * @param incx incx
   * @param dy dy
   * @param incy incy
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> void dswap(int n, RS[] dx, int incx, RS[] dy, int incy) {
    if (n > threadableVectorSize && CREATE_THREAD) {
      new DswapThread<RS,RM,CS,CM>().dswapTh(n, dx, incx, dy, incy);
    }

    new Dswap<RS,RM,CS,CM>().execute(n, dx, incx, dy, incy);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param n n
   * @param x x
   * @param incx incx
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> RS dnrm2(int n, RS[] x, int incx) {
    return new Dnrm2<RS,RM,CS,CM>().execute(n, x, incx);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param uplo uplo
   * @param n n
   * @param alpha alpha
   * @param a a
   * @param lda lda
   * @param x x
   * @param incx incx
   * @param beta beta
   * @param y y
   * @param incy incy
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dsymv(String uplo, int n, RS alpha, RS[] a, int lda, RS[] x, int incx, RS beta, RS[] y, int incy) {
    return new Dsymv<RS,RM,CS,CM>().execute(uplo, n, alpha, a, lda, x, incx, beta, y, incy);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param uplo uplo
   * @param n n
   * @param alpha alpha
   * @param x x
   * @param incx incx
   * @param y y
   * @param incy incy
   * @param a a
   * @param lda la
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dsyr2(String uplo, int n, RS alpha, RS[] x, int incx, RS[] y, int incy, RS[] a, int lda) {
    return new Dsyr2<RS,RM,CS,CM>().execute(uplo, n, alpha, x, incx, y, incy, a, lda);
  }

  /**
   * @param <RS> 実スカラーの型
   * @param <RM> 実行列の型
   * @param <CS> 複素スカラーの型
   * @param <CM> 複素行列の型
   * @param transa transa
   * @param transb transb
   * @param m m
   * @param n n
   * @param k k
   * @param alpha alpha
   * @param a a
   * @param lda lda
   * @param b b
   * @param ldb ldb
   * @param beta beta
   * @param c c
   * @param ldc ldc
   * @param thread thread
   * @return result
   */
  public static <RS extends RealNumericalScalar<RS, RM, CS, CM>, RM extends RealNumericalMatrix<RS, RM, CS, CM>, CS extends ComplexNumericalScalar<RS, RM, CS, CM>, CM extends ComplexNumericalMatrix<RS, RM, CS, CM>> int dgemm(String transa, String transb, int m, int n, int k, RS alpha, RS[] a, int lda, RS[] b, int ldb, RS beta, RS[] c, int ldc, boolean thread) {
    if (thread) {
      return new DgemmThread<RS,RM,CS,CM>().dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
    }

    return new Dgemm<RS,RM,CS,CM>().dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
  }
}