Beispiel #1
0
/*
 Symmetric rank-2 update.
 syr2(x, y, A, uplo='L', alpha=1.0, n=A.size[0], incx=1, incy=1,
     ldA=max(1,A.size[0]), offsetx=0, offsety=0, offsetA=0)
 PURPOSE
 Computes A := A + alpha*(x*y^T + y*x^T) with A real symmetric matrix of order n.
 ARGUMENTS
 x         float matrix
 y         float matrix
 A         float matrix
 alpha     real number (int or float)

 OPTIONS
 uplo      'L' or 'U'
 n         integer.  If negative, the default value is used.
 incx      nonzero integer
 incy      nonzero integer
 ldA       nonnegative integer.  ldA >= max(1,n).
           If zero the default value is used.
 offsetx   nonnegative integer
 offsety   nonnegative integer
 offsetA   nonnegative integer;
*/
func Syr2(X, Y, A matrix.Matrix, alpha matrix.Scalar, opts ...linalg.Option) (err error) {

	var params *linalg.Parameters
	params, err = linalg.GetParameters(opts...)
	if err != nil {
		return
	}
	ind := linalg.GetIndexOpts(opts...)
	err = check_level2_func(ind, fsyr2, X, Y, A, params)
	if err != nil {
		return
	}
	if !matrix.EqualTypes(A, X, Y) {
		return onError("Parameters not of same type")
	}
	switch X.(type) {
	case *matrix.FloatMatrix:
		Xa := X.(*matrix.FloatMatrix).FloatArray()
		Ya := X.(*matrix.FloatMatrix).FloatArray()
		Aa := A.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		if math.IsNaN(aval) {
			return onError("alpha not a number")
		}
		uplo := linalg.ParamString(params.Uplo)
		dsyr2(uplo, ind.N, aval, Xa[ind.OffsetX:], ind.IncX,
			Ya[ind.OffsetY:], ind.IncY,
			Aa[ind.OffsetA:], ind.LDa)
	case *matrix.ComplexMatrix:
		return onError("Not implemented yet for complx.Matrix")
	default:
		return onError("Unknown type, not implemented")
	}
	return
}
Beispiel #2
0
// Scales a vector by a constant (X := alpha*X).
//
// ARGUMENTS
//  X         float or complex matrix
//  alpha     number (float or complex singleton matrix).  Complex alpha is only
//            allowed if X is complex.
//
// OPTIONS
//  n         integer.  If n<0, the default value of n is used.
//            The default value is equal to 1+(len(x)-offset-1)/inc or 0
//            if len(x) > offset+1.
//  inc       positive integer, default = 1
//  offset    nonnegative integer, default = 0
//
func Scal(X matrix.Matrix, alpha matrix.Scalar, opts ...linalg.Option) (err error) {
	ind := linalg.GetIndexOpts(opts...)
	err = check_level1_func(ind, fscal, X, nil)
	if err != nil {
		return
	}
	if ind.Nx == 0 {
		return
	}
	switch X.(type) {
	case *matrix.ComplexMatrix:
		Xa := X.(*matrix.ComplexMatrix).ComplexArray()
		cval := alpha.Complex()
		zscal(ind.Nx, cval, Xa[ind.OffsetX:], ind.IncX)
	case *matrix.FloatMatrix:
		Xa := X.(*matrix.FloatMatrix).FloatArray()
		rval := alpha.Float()
		if math.IsNaN(rval) {
			return onError("alpha not float value")
		}
		dscal(ind.Nx, rval, Xa[ind.OffsetX:], ind.IncX)
	default:
		err = onError("not implemented for parameter types")
	}
	return
}
Beispiel #3
0
/*
 General matrix-matrix product. (L3)

 PURPOSE
 Computes
  C := alpha*A*B + beta*C     if transA = PNoTrans   and transB = PNoTrans.
  C := alpha*A^T*B + beta*C   if transA = PTrans     and transB = PNoTrans.
  C := alpha*A^H*B + beta*C   if transA = PConjTrans and transB = PNoTrans.
  C := alpha*A*B^T + beta*C   if transA = PNoTrans   and transB = PTrans.
  C := alpha*A^T*B^T + beta*C if transA = PTrans     and transB = PTrans.
  C := alpha*A^H*B^T + beta*C if transA = PConjTrans and transB = PTrans.
  C := alpha*A*B^H + beta*C   if transA = PNoTrans   and transB = PConjTrans.
  C := alpha*A^T*B^H + beta*C if transA = PTrans     and transB = PConjTrans.
  C := alpha*A^H*B^H + beta*C if transA = PConjTrans and transB = PConjTrans.

 The number of rows of the matrix product is m.  The number of  columns is n.
 The inner dimension is k.  If k=0, this reduces  to C := beta*C.

 ARGUMENTS
  A         float or complex matrix, m*k
  B         float or complex matrix, k*n
  C         float or complex matrix, m*n
  alpha     number (float or complex singleton matrix)
  beta      number (float or complex singleton matrix)

 OPTIONS
  transA    PNoTrans, PTrans or PConjTrans
  transB    PNoTrans, PTrans or PConjTrans
  m         integer.  If negative, the default value is used. The default value is
            m = A.Rows of if transA != PNoTrans m = A.Cols.
  n         integer.  If negative, the default value is used. The default value is
            n = (transB == PNoTrans) ? B.Cols : B.Rows.
  k         integer.  If negative, the default value is used. The default value is
            k=A.Cols or if transA != PNoTrans) k = A.Rows, transA=PNoTrans.
            If the default value is used it should also be equal to
            (transB == PNoTrans) ? B.Rows : B.Cols.
  ldA       nonnegative integer.  ldA >= max(1,m) of if transA != NoTrans max(1,k).
            If zero, the default value is used.
  ldB       nonnegative integer.  ldB >= max(1,k) or if transB != NoTrans max(1,n).
            If zero, the default value is used.
  ldC       nonnegative integer.  ldC >= max(1,m).
            If zero, the default value is used.
  offsetA   nonnegative integer
  offsetB   nonnegative integer
  offsetC   nonnegative integer;
*/
func Gemm(A, B, C matrix.Matrix, alpha, beta matrix.Scalar, opts ...linalg.Option) (err error) {

	params, e := linalg.GetParameters(opts...)
	if e != nil {
		err = e
		return
	}
	ind := linalg.GetIndexOpts(opts...)
	err = check_level3_func(ind, fgemm, A, B, C, params)
	if err != nil {
		return
	}
	if ind.M == 0 || ind.N == 0 {
		return
	}
	if !matrix.EqualTypes(A, B, C) {
		return onError("Parameters not of same type")
	}
	switch A.(type) {
	case *matrix.FloatMatrix:
		Aa := A.(*matrix.FloatMatrix).FloatArray()
		Ba := B.(*matrix.FloatMatrix).FloatArray()
		Ca := C.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		bval := beta.Float()
		if math.IsNaN(aval) || math.IsNaN(bval) {
			return onError("alpha or beta not a number")
		}
		transB := linalg.ParamString(params.TransB)
		transA := linalg.ParamString(params.TransA)
		dgemm(transA, transB, ind.M, ind.N, ind.K, aval,
			Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb, bval,
			Ca[ind.OffsetC:], ind.LDc)

	case *matrix.ComplexMatrix:
		Aa := A.(*matrix.ComplexMatrix).ComplexArray()
		Ba := B.(*matrix.ComplexMatrix).ComplexArray()
		Ca := C.(*matrix.ComplexMatrix).ComplexArray()
		aval := alpha.Complex()
		if cmplx.IsNaN(aval) {
			return onError("alpha not a number")
		}
		bval := beta.Complex()
		if cmplx.IsNaN(bval) {
			return onError("beta not a number")
		}
		transB := linalg.ParamString(params.TransB)
		transA := linalg.ParamString(params.TransA)
		zgemm(transA, transB, ind.M, ind.N, ind.K, aval,
			Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb, bval,
			Ca[ind.OffsetC:], ind.LDc)
	default:
		return onError("Unknown type, not implemented")
	}
	return
}
Beispiel #4
0
/*
 Rank-k update of symmetric matrix. (L3)

 Syrk(A, C, alpha=1.0, beta=0.0, uplo=PLower, trans=PNoTrans, n=-1,
 k=-1, ldA=max(1,A.Rows), ldC=max(1,C.Rows), offsetA=0, offsetB=0)

 PURPOSE
  C := alpha*A*A^T + beta*C, if trans is PNoTrans
  C := alpha*A^T*A + beta*C, if trans is PTrans
  C := alpha*A^H*A + beta*C, if trans is PConjTrans

 C is symmetric (real or complex) of order n.
 The inner dimension of the matrix product is k.  If k=0 this is
 interpreted as C := beta*C.

 ARGUMENTS
  A         float or complex n*k matrix
  C         float or complex n*n matrix.  Must have the same type as A.
  alpha     number (float or complex singleton matrix).  Complex alpha is only
            allowed if A is complex.
  beta      number (float or complex singleton matrix).  Complex beta is only
            allowed if A is complex.

 OPTIONS
  uplo      PLower or PUpper
  trans     PNoTrans, PTrans or PConjTrans
  n         integer.  If negative, the default value is used.
            The default value is  n = A.Rows of if trans != PNoTrans) n = A.Cols.
  k         integer.  If negative, the default value is used.
            The default value is k = A.Cols or if trans != PNoTrans k = A.Rows.
  ldA       nonnegative integer. ldA >= max(1, n) or if trans != PNoTrans max(1, k).
            If zero, the default value [max(1, A.Rows)] is used.
  ldC       nonnegative integer.  ldC >= max(1,n).  If zero, the default value is used.
  offsetA   nonnegative integer
  offsetC   nonnegative integer;
*/
func Syrk(A, C matrix.Matrix, alpha, beta matrix.Scalar, opts ...linalg.Option) (err error) {

	params, e := linalg.GetParameters(opts...)
	if e != nil {
		err = e
		return
	}
	ind := linalg.GetIndexOpts(opts...)
	err = check_level3_func(ind, fsyrk, A, nil, C, params)
	if e != nil || err != nil {
		return
	}
	if !matrix.EqualTypes(A, C) {
		return onError("Parameters not of same type")
	}
	switch A.(type) {
	case *matrix.FloatMatrix:
		Aa := A.(*matrix.FloatMatrix).FloatArray()
		Ca := C.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		bval := beta.Float()
		if math.IsNaN(aval) || math.IsNaN(bval) {
			return onError("alpha or beta not a number")
		}
		uplo := linalg.ParamString(params.Uplo)
		trans := linalg.ParamString(params.Trans)
		dsyrk(uplo, trans, ind.N, ind.K, aval, Aa[ind.OffsetA:], ind.LDa, bval,
			Ca[ind.OffsetC:], ind.LDc)
	case *matrix.ComplexMatrix:
		Aa := A.(*matrix.ComplexMatrix).ComplexArray()
		Ca := C.(*matrix.ComplexMatrix).ComplexArray()
		aval := alpha.Complex()
		if cmplx.IsNaN(aval) {
			return onError("alpha not a number")
		}
		bval := beta.Complex()
		if cmplx.IsNaN(bval) {
			return onError("beta not a number")
		}
		uplo := linalg.ParamString(params.Uplo)
		trans := linalg.ParamString(params.Trans)
		zsyrk(uplo, trans, ind.N, ind.K, aval, Aa[ind.OffsetA:], ind.LDa, bval,
			Ca[ind.OffsetC:], ind.LDc)
	default:
		return onError("Unknown type, not implemented")
	}

	return
}
Beispiel #5
0
/*
 Matrix-vector product with a real symmetric or complex hermitian band matrix.

 Computes with A real symmetric and  banded of order n and with bandwidth k.
  Y := alpha*A*X + beta*Y

 ARGUMENTS
  A         float or complex n*n matrix
  X         float or complex n*1 matrix
  Y         float or complex n*1 matrix
  alpha     number (float or complex singleton matrix)
  beta      number (float or complex singleton matrix)

 OPTIONS
  uplo      PLower or PUpper
  n         integer.  If negative, the default value is used.
  k         integer.  If negative, the default value is used.
            The default value is k = max(0,A.Rows()-1).
  ldA       nonnegative integer.  ldA >= k+1.
            If zero, the default vaule is used.
  incx      nonzero integer
  incy      nonzero integer
  offsetA   nonnegative integer
  offsetx   nonnegative integer
  offsety   nonnegative integer

*/
func Hbmv(A, X, Y matrix.Matrix, alpha, beta matrix.Scalar, opts ...linalg.Option) (err error) {

	var params *linalg.Parameters
	params, err = linalg.GetParameters(opts...)
	if err != nil {
		return
	}
	ind := linalg.GetIndexOpts(opts...)
	err = check_level2_func(ind, fsbmv, X, Y, A, params)
	if err != nil {
		return
	}
	if ind.N == 0 {
		return
	}
	if !matrix.EqualTypes(A, X, Y) {
		return onError("Parameters not of same type")
	}
	switch X.(type) {
	case *matrix.FloatMatrix:
		Xa := X.(*matrix.FloatMatrix).FloatArray()
		Ya := Y.(*matrix.FloatMatrix).FloatArray()
		Aa := A.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		bval := beta.Float()
		if math.IsNaN(aval) || math.IsNaN(bval) {
			return onError("alpha or beta not a number")
		}
		uplo := linalg.ParamString(params.Uplo)
		dsbmv(uplo, ind.N, ind.K, aval, Aa[ind.OffsetA:], ind.LDa,
			Xa[ind.OffsetX:], ind.IncX, bval, Ya[ind.OffsetY:], ind.IncY)

	case *matrix.ComplexMatrix:
		Xa := X.(*matrix.ComplexMatrix).ComplexArray()
		Ya := Y.(*matrix.ComplexMatrix).ComplexArray()
		Aa := A.(*matrix.ComplexMatrix).ComplexArray()
		aval := alpha.Complex()
		bval := beta.Complex()
		uplo := linalg.ParamString(params.Uplo)
		zhbmv(uplo, ind.N, ind.K, aval, Aa[ind.OffsetA:], ind.LDa,
			Xa[ind.OffsetX:], ind.IncX, bval, Ya[ind.OffsetY:], ind.IncY)
		//zhbmv(uplo, ind.N, aval, Aa[ind.OffsetA:], ind.LDa,
		//	Xa[ind.OffsetX:], ind.IncX,
		//	bval, Ya[ind.OffsetY:], ind.IncY)
	default:
		return onError("Unknown type, not implemented")
	}
	return
}
Beispiel #6
0
/*
 Solution of a triangular system of equations with multiple righthand sides. (L3)

 Trsm(A, B, alpha, side=PLeft, uplo=PLower, transA=PNoTrans, diag=PNonUnit,
 m=-1, n=-1, ldA=max(1,A.Rows), ldB=max(1,B.Rows), offsetA=0, offsetB=0)

 Computes
  B := alpha*A^{-1}*B if transA is PNoTrans   and side = PLeft
  B := alpha*B*A^{-1} if transA is PNoTrans   and side = PRight
  B := alpha*A^{-T}*B if transA is PTrans     and side = PLeft
  B := alpha*B*A^{-T} if transA is PTrans     and side = PRight
  B := alpha*A^{-H}*B if transA is PConjTrans and side = PLeft
  B := alpha*B*A^{-H} if transA is PConjTrans and side = PRight

 B is m by n and A is triangular.  The code does not verify whether A is nonsingular.

 ARGUMENTS
  A         float or complex matrix.
  B         float or complex matrix.  Must have the same type as A.
  alpha     number (float or complex).  Complex alpha is only
            allowed if A is complex.

 OPTIONS
  side      PLeft or PRight
  uplo      PLower or PUpper
  transA    PNoTrans or PTrans
  diag      PNonUnit or PUnit
  m         integer.  If negative, the default value is used.
            The default value is m = A.Rows or if side == PRight m = B.Rows
            If the default value is used and side is PLeft, m must be equal to A.Cols.
  n         integer.  If negative, the default value is used.
            The default value is n = B.Cols or if side )= PRight n = A.Rows.
            If the default value is used and side is PRight, n must be equal to A.Cols.
  ldA       nonnegative integer.
            ldA >= max(1,m) of if  side == PRight lda >= max(1,n).
            If zero, the default value is used.
  ldB       nonnegative integer.  ldB >= max(1,m).
            If zero, the default value is used.
  offsetA   nonnegative integer
  offsetB   nonnegative integer
*/
func Trsm(A, B matrix.Matrix, alpha matrix.Scalar, opts ...linalg.Option) (err error) {

	params, e := linalg.GetParameters(opts...)
	if e != nil {
		err = e
		return
	}
	ind := linalg.GetIndexOpts(opts...)
	err = check_level3_func(ind, ftrsm, A, B, nil, params)
	if err != nil {
		return
	}
	if !matrix.EqualTypes(A, B) {
		return onError("Parameters not of same type")
	}
	switch A.(type) {
	case *matrix.FloatMatrix:
		Aa := A.(*matrix.FloatMatrix).FloatArray()
		Ba := B.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		if math.IsNaN(aval) {
			return onError("alpha or beta not a number")
		}
		uplo := linalg.ParamString(params.Uplo)
		transA := linalg.ParamString(params.TransA)
		side := linalg.ParamString(params.Side)
		diag := linalg.ParamString(params.Diag)
		dtrsm(side, uplo, transA, diag, ind.M, ind.N, aval,
			Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb)
	case *matrix.ComplexMatrix:
		Aa := A.(*matrix.ComplexMatrix).ComplexArray()
		Ba := B.(*matrix.ComplexMatrix).ComplexArray()
		aval := alpha.Complex()
		if cmplx.IsNaN(aval) {
			return onError("alpha  not a number")
		}
		uplo := linalg.ParamString(params.Uplo)
		transA := linalg.ParamString(params.TransA)
		side := linalg.ParamString(params.Side)
		diag := linalg.ParamString(params.Diag)
		ztrsm(side, uplo, transA, diag, ind.M, ind.N, aval,
			Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb)
	default:
		return onError("Unknown type, not implemented")
	}
	return
}
Beispiel #7
0
/*
 General rank-1 update. (L2)

 Ger(X, Y, A, alpha=1.0, m=A.Rows, n=A.Cols, incx=1,
 incy=1, ldA=max(1,A.Rows), offsetx=0, offsety=0, offsetA=0)

 COMPUTES
  A := A + alpha*X*Y^H with A m*n, real or complex.

 ARGUMENTS
  X         float or complex matrix.
  Y         float or complex matrix. Must have the same type as X.
  A         float or complex matrix. Must have the same type as X.
  alpha     number (float or complex singleton matrix).

 OPTIONS
  m         integer.  If negative, the default value is used.
  n         integer.  If negative, the default value is used.
  incx      nonzero integer
  incy      nonzero integer
  ldA       nonnegative integer.  ldA >= max(1,m).
            If zero, the default value is used.
  offsetx   nonnegative integer
  offsety   nonnegative integer
  offsetA   nonnegative integer;

*/
func Ger(X, Y, A matrix.Matrix, alpha matrix.Scalar, opts ...linalg.Option) (err error) {

	var params *linalg.Parameters
	if !matrix.EqualTypes(A, X, Y) {
		err = onError("Parameters not of same type")
		return
	}
	params, err = linalg.GetParameters(opts...)
	if err != nil {
		return
	}
	ind := linalg.GetIndexOpts(opts...)
	err = check_level2_func(ind, fger, X, Y, A, params)
	if err != nil {
		return
	}
	if ind.N == 0 || ind.M == 0 {
		return
	}
	switch X.(type) {
	case *matrix.FloatMatrix:
		Xa := X.(*matrix.FloatMatrix).FloatArray()
		Ya := Y.(*matrix.FloatMatrix).FloatArray()
		Aa := A.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		if math.IsNaN(aval) {
			return onError("alpha not a number")
		}
		dger(ind.M, ind.N, aval, Xa[ind.OffsetX:], ind.IncX,
			Ya[ind.OffsetY:], ind.IncY, Aa[ind.OffsetA:], ind.LDa)

	case *matrix.ComplexMatrix:
		Xa := X.(*matrix.ComplexMatrix).ComplexArray()
		Ya := Y.(*matrix.ComplexMatrix).ComplexArray()
		Aa := A.(*matrix.ComplexMatrix).ComplexArray()
		aval := alpha.Complex()
		if cmplx.IsNaN(aval) {
			return onError("alpha not a number")
		}
		zgerc(ind.M, ind.N, aval, Xa[ind.OffsetX:], ind.IncX,
			Ya[ind.OffsetY:], ind.IncY, Aa[ind.OffsetA:], ind.LDa)

	default:
		return onError("Unknown type, not implemented")
	}
	return
}
Beispiel #8
0
/*
 Matrix-vector product with a general banded matrix. (L2)

 Computes
   Y := alpha*A*X + beta*Y,   if trans = PNoTrans
   Y := alpha*A^T*X + beta*Y, if trans = PTrans
   Y := beta*y,               if n=0, m>0, and trans = PNoTrans
   Y := beta*y,               if n>0, m=0, and trans = PTrans

 The matrix A is m by n with upper bandwidth ku and lower bandwidth kl.
 Returns immediately if n=0 and trans is 'Trans', or if m=0 and trans is 'N'.


 ARGUMENTS
   X         float n*1 matrix.
   Y         float m*1 matrix
   A         float m*n matrix.
   alpha     number (float).
   beta      number (float).

 OPTIONS
   trans     NoTrans or Trans
   m         nonnegative integer, default A.Rows()
   kl        nonnegative integer
   n         nonnegative integer.  If negative, the default value is used.
   ku        nonnegative integer.  If negative, the default value is used.
   ldA       positive integer.  ldA >= kl+ku+1. If zero, the default value is used.
   incx      nonzero integer, default =1
   incy      nonzero integer, default =1
   offsetA   nonnegative integer, default =0
   offsetx   nonnegative integer, default =0
   offsety   nonnegative integer, default =0

*/
func Gbmv(A, X, Y matrix.Matrix, alpha, beta matrix.Scalar, opts ...linalg.Option) (err error) {

	var params *linalg.Parameters
	params, err = linalg.GetParameters(opts...)
	if err != nil {
		return
	}
	ind := linalg.GetIndexOpts(opts...)
	err = check_level2_func(ind, fgbmv, X, Y, A, params)
	if err != nil {
		return
	}
	if ind.M == 0 && ind.N == 0 {
		return
	}
	if !matrix.EqualTypes(A, X, Y) {
		return onError("Parameters not of same type")
	}
	switch X.(type) {
	case *matrix.FloatMatrix:
		Xa := X.(*matrix.FloatMatrix).FloatArray()
		Ya := Y.(*matrix.FloatMatrix).FloatArray()
		Aa := A.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		bval := beta.Float()
		if math.IsNaN(aval) || math.IsNaN(bval) {
			return onError("alpha or beta not a number")
		}
		if params.Trans == linalg.PNoTrans && ind.N == 0 {
			dscal(ind.M, bval, Ya[ind.OffsetY:], ind.IncY)
		} else if params.Trans == linalg.PTrans && ind.M == 0 {
			dscal(ind.N, bval, Ya[ind.OffsetY:], ind.IncY)
		} else {
			trans := linalg.ParamString(params.Trans)
			dgbmv(trans, ind.M, ind.N, ind.Kl, ind.Ku,
				aval, Aa[ind.OffsetA:], ind.LDa, Xa[ind.OffsetX:], ind.IncX,
				bval, Ya[ind.OffsetY:], ind.IncY)
		}
	case *matrix.ComplexMatrix:
		return onError("Not implemented yet for complx.Matrix")
	default:
		return onError("Unknown type, not implemented")
	}
	return
}
Beispiel #9
0
// Constant times a vector plus a vector (Y := alpha*X+Y).
//
// ARGUMENTS
//   X         float or complex matrix
//   Y         float or complex matrix.  Must have the same type as X.
//   alpha     number (float or complex singleton matrix).  Complex alpha is only
//             allowed if x is complex.
//
// OPTIONS
//   n         integer.  If n<0, the default value of n is used.
//             The default value is equal to 1+(len(x)-offsetx-1)/incx
//             or 0 if  len(x) >= offsetx+1
//   incx      nonzero integer
//   incy      nonzero integer
//   offsetx   nonnegative integer
//   offsety   nonnegative integer;
//
func Axpy(X, Y matrix.Matrix, alpha matrix.Scalar, opts ...linalg.Option) (err error) {
	ind := linalg.GetIndexOpts(opts...)
	err = check_level1_func(ind, faxpy, X, Y)
	if err != nil {
		return
	}
	if ind.Nx == 0 {
		return
	}
	sameType := matrix.EqualTypes(X, Y)
	if !sameType {
		err = onError("arrays not same type")
		return
	}
	switch X.(type) {
	case *matrix.ComplexMatrix:
		Xa := X.(*matrix.ComplexMatrix).ComplexArray()
		Ya := Y.(*matrix.ComplexMatrix).ComplexArray()
		aval := alpha.Complex()
		if cmplx.IsNaN(aval) {
			return onError("alpha not complex value")
		}
		zaxpy(ind.Nx, aval, Xa[ind.OffsetX:],
			ind.IncX, Ya[ind.OffsetY:], ind.IncY)
	case *matrix.FloatMatrix:
		Xa := X.(*matrix.FloatMatrix).FloatArray()
		Ya := Y.(*matrix.FloatMatrix).FloatArray()
		aval := alpha.Float()
		if math.IsNaN(aval) {
			return onError("alpha not float value")
		}
		daxpy(ind.Nx, aval, Xa[ind.OffsetX:],
			ind.IncX, Ya[ind.OffsetY:], ind.IncY)
	default:
		err = onError("not implemented for parameter types")
	}
	return
}