// Inverse UNIT diagonal tridiagonal matrix func unblockedInverseUnitLower(A *matrix.FloatMatrix) (err error) { var ATL, ATR, ABL, ABR matrix.FloatMatrix var A00, a10t, a11, A20, a21, A22 matrix.FloatMatrix err = nil partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, pTOPLEFT) for ATL.Rows() < A.Rows() { repartition2x2to3x3(&ATL, &A00, nil, nil, &a10t, &a11, nil, &A20, &a21, &A22, A, 1, pBOTTOMRIGHT) // ------------------------------------------------- // a21 = -a21 Scale(&a21, -1.0) // A20 = A20 + a21*a10.t MVRankUpdate(&A20, &a21, &a10t, 1.0) // ------------------------------------------------- continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, pBOTTOMRIGHT) } return }
func InverseTrm(A *matrix.FloatMatrix, flags Flags, nb int) (*matrix.FloatMatrix, error) { var err error = nil if nb == 0 || A.Cols() < nb { if flags&UNIT != 0 { if flags&LOWER != 0 { err = unblockedInverseUnitLower(A) } else { err = unblockedInverseUnitUpper(A) } } else { if flags&LOWER != 0 { err = unblockedInverseLower(A) } else { err = unblockedInverseUpper(A) } } } else { if flags&LOWER != 0 { err = blockedInverseLower(A, flags, nb) } else { err = blockedInverseUpper(A, flags, nb) } } return A, err }
// Inverse NON-UNIT diagonal tridiagonal matrix func unblockedInverseUpper(A *matrix.FloatMatrix) (err error) { var ATL, ATR, ABL, ABR matrix.FloatMatrix var A00, a01, A02, a11, a12t, A22 matrix.FloatMatrix err = nil partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, pTOPLEFT) for ATL.Rows() < A.Rows() { repartition2x2to3x3(&ATL, &A00, &a01, &A02, nil, &a11, &a12t, nil, nil, &A22, A, 1, pBOTTOMRIGHT) // ------------------------------------------------- aval := a11.Float() // a12 = -a12/a11 InvScale(&a12t, -aval) // A02 = A02 + a01*a12 MVRankUpdate(&A02, &a01, &a12t, 1.0) // a01 = a01/a11 InvScale(&a01, aval) // a11 = 1.0/a11 a11.SetAt(0, 0, 1.0/aval) // ------------------------------------------------- continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, pBOTTOMRIGHT) } return }
func blockedInverseUpper(A *matrix.FloatMatrix, flags Flags, nb int) (err error) { var ATL, ATR, ABL, ABR matrix.FloatMatrix var A00, A01, A02, A11, A12, A22 matrix.FloatMatrix err = nil partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, pTOPLEFT) for ATL.Rows() < A.Rows() { repartition2x2to3x3(&ATL, &A00, &A01, &A02, nil, &A11, &A12, nil, nil, &A22, A, nb, pBOTTOMRIGHT) // ------------------------------------------------- // libflame, variant 1 // A01 = A00*A01 MultTrm(&A01, &A00, 1.0, flags) // A01 = -A01 / triu(A11) SolveTrm(&A01, &A11, -1.0, flags|RIGHT) // A11 = inv(A11) if flags&UNIT != 0 { unblockedInverseUnitUpper(&A11) } else { unblockedInverseUpper(&A11) } // ------------------------------------------------- continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &A11, &A22, A, pBOTTOMRIGHT) } return }
func runRefTest(A *matrix.FloatMatrix, ntest, LB int) time.Duration { var mintime time.Duration N := A.Cols() tau := matrix.FloatZeros(N, 1) fnc := func() { ERRlapack = lapack.Geqrf(A, tau) } A0 := A.Copy() for n := 0; n < ntest; n++ { if n > 0 { // restore original A A0.CopyTo(A) tau.Scale(0.0) } mperf.FlushCache() time0 := mperf.Timeit(fnc) if n == 0 || time0 < mintime { mintime = time0 } } return mintime }
func TestSolveLeastSquaresQRT(t *testing.T) { M := 60 N := 40 K := 30 nb := 12 A := matrix.FloatUniform(M, N) B := matrix.FloatZeros(M, K) X0 := matrix.FloatUniform(N, K) // B = A*X0 Mult(B, A, X0, 1.0, 0.0, NOTRANS) W := matrix.FloatZeros(N, nb) T := matrix.FloatZeros(N, N) QR, err := DecomposeQRT(A, T, W, nb) if err != nil { t.Logf("decompose error: %v\n", err) } // B' = A.-1*B err = SolveQRT(B, QR, T, W, NOTRANS, nb) // expect B[0:N, 0:K] == X0, B[N:M, 0:K] == 0.0 var Xref matrix.FloatMatrix Bref := matrix.FloatZeros(M, K) Bref.SubMatrix(&Xref, 0, 0, N, K) Xref.Plus(X0) Bref.Minus(B) t.Logf("\nmin ||B - A*X0||\n\twhere B = A*X0\n") t.Logf("||B - A*X0||_1 ~~ 0.0: %e\n", NormP(Bref, NORM_ONE)) }
func updateBlas(t *testing.T, Y1, Y2, C1, C2, T, W *matrix.FloatMatrix) { if W.Rows() != C1.Cols() { panic("W.Rows != C1.Cols") } // W = C1.T ScalePlus(W, C1, 0.0, 1.0, TRANSB) //fmt.Printf("W = C1.T:\n%v\n", W) // W = C1.T*Y1 blas.TrmmFloat(Y1, W, 1.0, linalg.OptLower, linalg.OptUnit, linalg.OptRight) t.Logf("W = C1.T*Y1:\n%v\n", W) // W = W + C2.T*Y2 blas.GemmFloat(C2, Y2, W, 1.0, 1.0, linalg.OptTransA) t.Logf("W = W + C2.T*Y2:\n%v\n", W) // --- here: W == C.T*Y --- // W = W*T blas.TrmmFloat(T, W, 1.0, linalg.OptUpper, linalg.OptRight) t.Logf("W = C.T*Y*T:\n%v\n", W) // --- here: W == C.T*Y*T --- // C2 = C2 - Y2*W.T blas.GemmFloat(Y2, W, C2, -1, 1.0, linalg.OptTransB) t.Logf("C2 = C2 - Y2*W.T:\n%v\n", C2) // W = Y1*W.T ==> W.T = W*Y1.T blas.TrmmFloat(Y1, W, 1.0, linalg.OptLower, linalg.OptUnit, linalg.OptRight, linalg.OptTrans) t.Logf("W.T = W*Y1.T:\n%v\n", W) // C1 = C1 - W.T ScalePlus(C1, W, 1.0, -1.0, TRANSB) //fmt.Printf("C1 = C1 - W.T:\n%v\n", C1) // --- here: C = (I - Y*T*Y.T).T * C --- }
func runTest(A *matrix.FloatMatrix, ntest, LB int) time.Duration { var flags matops.Flags var mintime time.Duration flags = matops.LOWER if testUpper { flags = matops.UPPER } fnc := func() { _, ERRmatops = matops.DecomposeCHOL(A, flags, LB) } A0 := A.Copy() for n := 0; n < ntest; n++ { if n > 0 { // restore original A A0.CopyTo(A) } mperf.FlushCache() time0 := mperf.Timeit(fnc) if n == 0 || time0 < mintime { mintime = time0 } if verbose { fmt.Printf("%.4f ms\n", time0.Seconds()*1000.0) } } return mintime }
func setDiagonal(M *matrix.FloatMatrix, srow, scol, erow, ecol int, val float64) { for i := srow; i < erow; i++ { if i < ecol { M.SetAt(i, i, val) } } }
// max |x| func AMax(X *matrix.FloatMatrix) float64 { ix := IAMax(X) if ix == -1 { return math.NaN() } return X.GetIndex(ix) }
// See function Syrk. func SyrkFloat(A, C *matrix.FloatMatrix, alpha, beta float64, 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 ind.N == 0 { return } Aa := A.FloatArray() Ca := C.FloatArray() uplo := linalg.ParamString(params.Uplo) trans := linalg.ParamString(params.Trans) //diag := linalg.ParamString(params.Diag) dsyrk(uplo, trans, ind.N, ind.K, alpha, Aa[ind.OffsetA:], ind.LDa, beta, Ca[ind.OffsetC:], ind.LDc) return }
func runRefTest(A *matrix.FloatMatrix, ntest, LB int) time.Duration { var mintime time.Duration lopt := linalg.OptLower if testUpper { lopt = linalg.OptUpper } fnc := func() { ERRlapack = lapack.Potrf(A, lopt) } A0 := A.Copy() for n := 0; n < ntest; n++ { if n > 0 { // restore original A A0.CopyTo(A) } mperf.FlushCache() time0 := mperf.Timeit(fnc) if n == 0 || time0 < mintime { mintime = time0 } } return mintime }
/* Copy x to y using packed storage. The vector x is an element of S, with the 's' components stored in unpacked storage. On return, x is copied to y with the 's' components stored in packed storage and the off-diagonal entries scaled by sqrt(2). */ func pack(x, y *matrix.FloatMatrix, dims *sets.DimensionSet, opts ...la_.Option) (err error) { /*DEBUGGED*/ err = nil mnl := la_.GetIntOpt("mnl", 0, opts...) offsetx := la_.GetIntOpt("offsetx", 0, opts...) offsety := la_.GetIntOpt("offsety", 0, opts...) nlq := mnl + dims.At("l")[0] + dims.Sum("q") blas.Copy(x, y, &la_.IOpt{"n", nlq}, &la_.IOpt{"offsetx", offsetx}, &la_.IOpt{"offsety", offsety}) iu, ip := offsetx+nlq, offsety+nlq for _, n := range dims.At("s") { for k := 0; k < n; k++ { blas.Copy(x, y, &la_.IOpt{"n", n - k}, &la_.IOpt{"offsetx", iu + k*(n+1)}, &la_.IOpt{"offsety", ip}) y.SetIndex(ip, (y.GetIndex(ip) / math.Sqrt(2.0))) ip += n - k } iu += n * n } np := dims.SumPacked("s") blas.ScalFloat(y, math.Sqrt(2.0), &la_.IOpt{"n", np}, &la_.IOpt{"offset", offsety + nlq}) return }
func trmvTest(t *testing.T, A *matrix.FloatMatrix, flags Flags, nb int) bool { N := A.Cols() //S := 0 //E := A.Cols() X0 := matrix.FloatWithValue(A.Rows(), 1, 2.0) X1 := X0.Copy() trans := linalg.OptNoTrans if flags&TRANS != 0 { trans = linalg.OptTrans } diag := linalg.OptNonUnit if flags&UNIT != 0 { diag = linalg.OptUnit } uplo := linalg.OptUpper if flags&LOWER != 0 { uplo = linalg.OptLower } blas.TrmvFloat(A, X0, uplo, diag, trans) Ar := A.FloatArray() Xr := X1.FloatArray() if nb == 0 { DTrimvUnblkMV(Xr, Ar, flags, 1, A.LeadingIndex(), N) } result := X0.AllClose(X1) t.Logf(" X0 == X1: %v\n", result) if !result && A.Rows() < 8 { t.Logf(" BLAS TRMV X0:\n%v\n", X0) t.Logf(" DTrmv X1:\n%v\n", X1) } return result }
// In-place version of pack(), which also accepts matrix arguments x. // The columns of x are elements of S, with the 's' components stored // in unpacked storage. On return, the 's' components are stored in // packed storage and the off-diagonal entries are scaled by sqrt(2). // func pack2(x *matrix.FloatMatrix, dims *sets.DimensionSet, mnl int) (err error) { if len(dims.At("s")) == 0 { return nil } const sqrt2 = 1.41421356237309504880 iu := mnl + dims.Sum("l", "q") ip := iu row := matrix.FloatZeros(1, x.Cols()) //fmt.Printf("x.size = %d %d\n", x.Rows(), x.Cols()) for _, n := range dims.At("s") { for k := 0; k < n; k++ { cnt := n - k row = x.GetRow(iu+(n+1)*k, row) //fmt.Printf("%02d: %v\n", iu+(n+1)*k, x.FloatArray()) x.SetRow(ip, row) for i := 1; i < n-k; i++ { row = x.GetRow(iu+(n+1)*k+i, row) //fmt.Printf("%02d: %v\n", iu+(n+1)*k+i, x.FloatArray()) x.SetRow(ip+i, row.Scale(sqrt2)) } ip += cnt } iu += n * n } return nil }
/* * ( a11 a12 ) ( 1 0 )( d1 0 )( l l21.t ) * ( a21 A22 ) ( l21 L22 )( 0 A22 )( 0 L22.t ) * * a11 = d1 * a21 = l21*d1 => l21 = a21/d1 * A22 = l21*d1*l21.t + L22*D2*L22.t => L22 = A22 - l21*d1*l21t */ func unblkLowerLDLnoPiv(A *matrix.FloatMatrix) (err error) { var ATL, ATR, ABL, ABR matrix.FloatMatrix var A00, a10, a11, A20, a21, A22 matrix.FloatMatrix err = nil partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, pTOPLEFT) for ATL.Rows() < A.Rows() { repartition2x2to3x3(&ATL, &A00, nil, nil, &a10, &a11, nil, &A20, &a21, &A22, A, 1, pBOTTOMRIGHT) // -------------------------------------------------------- // d11 = a11; no-op // A22 = A22 - l21*d11*l21.T = A22 - a21*a21.T/a11; triangular update err = MVUpdateTrm(&A22, &a21, &a21, -1.0/a11.Float(), LOWER) // l21 = a21/a11 InvScale(&a21, a11.Float()) // --------------------------------------------------------- continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, pBOTTOMRIGHT) } return }
// See function Trsm. func TrsmFloat(A, B *matrix.FloatMatrix, alpha float64, 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 ind.N == 0 || ind.M == 0 { return } Aa := A.FloatArray() Ba := B.FloatArray() 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, alpha, Aa[ind.OffsetA:], ind.LDa, Ba[ind.OffsetB:], ind.LDb) return }
// blocked LU decomposition w/o pivots, FLAME LU nopivots variant 5 func blockedLUnoPiv(A *matrix.FloatMatrix, nb int) (err error) { var ATL, ATR, ABL, ABR matrix.FloatMatrix var A00, A01, A02, A10, A11, A12, A20, A21, A22 matrix.FloatMatrix err = nil partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, pTOPLEFT) for ATL.Rows() < A.Rows() { repartition2x2to3x3(&ATL, &A00, &A01, &A02, &A10, &A11, &A12, &A20, &A21, &A22, A, nb, pBOTTOMRIGHT) // A00 = LU(A00) unblockedLUnoPiv(&A11) // A12 = trilu(A00)*A12.-1 (TRSM) SolveTrm(&A12, &A11, 1.0, LEFT|LOWER|UNIT) // A21 = A21.-1*triu(A00) (TRSM) SolveTrm(&A21, &A11, 1.0, RIGHT|UPPER) // A22 = A22 - A21*A12 Mult(&A22, &A21, &A12, -1.0, 1.0, NOTRANS) continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &A11, &A22, A, pBOTTOMRIGHT) } return }
/* Matrix-vector multiplication. A is a matrix or spmatrix of size (m, n) where N = dims['l'] + sum(dims['q']) + sum( k**2 for k in dims['s'] ) representing a mapping from R^n to S. If trans is 'N': y := alpha*A*x + beta * y (trans = 'N'). x is a vector of length n. y is a vector of length N. If trans is 'T': y := alpha*A'*x + beta * y (trans = 'T'). x is a vector of length N. y is a vector of length n. The 's' components in S are stored in unpacked 'L' storage. */ func sgemv(A, x, y *matrix.FloatMatrix, alpha, beta float64, dims *sets.DimensionSet, opts ...la_.Option) error { m := dims.Sum("l", "q") + dims.SumSquared("s") n := la_.GetIntOpt("n", -1, opts...) if n == -1 { n = A.Cols() } trans := la_.GetIntOpt("trans", int(la_.PNoTrans), opts...) offsetX := la_.GetIntOpt("offsetx", 0, opts...) offsetY := la_.GetIntOpt("offsety", 0, opts...) offsetA := la_.GetIntOpt("offseta", 0, opts...) if trans == int(la_.PTrans) && alpha != 0.0 { trisc(x, dims, offsetX) //fmt.Printf("trisc x=\n%v\n", x.ConvertToString()) } //fmt.Printf("alpha=%.4f beta=%.4f m=%d n=%d\n", alpha, beta, m, n) //fmt.Printf("A=\n%v\nx=\n%v\ny=\n%v\n", A, x.ConvertToString(), y.ConvertToString()) err := blas.GemvFloat(A, x, y, alpha, beta, &la_.IOpt{"trans", trans}, &la_.IOpt{"n", n}, &la_.IOpt{"m", m}, &la_.IOpt{"offseta", offsetA}, &la_.IOpt{"offsetx", offsetX}, &la_.IOpt{"offsety", offsetY}) //fmt.Printf("gemv y=\n%v\n", y.ConvertToString()) if trans == int(la_.PTrans) && alpha != 0.0 { triusc(x, dims, offsetX) } return err }
func (p *acenterProg) F2(x, z *matrix.FloatMatrix) (f, Df, H *matrix.FloatMatrix, err error) { f, Df, err = p.F1(x) u := matrix.Pow(x, 2.0).Scale(-1.0).Add(1.0) z0 := z.GetIndex(0) u2 := matrix.Pow(u, 2.0) hd := matrix.Div(matrix.Add(u2, 1.0), u2).Scale(2 * z0) H = matrix.FloatDiagonal(hd.NumElements(), hd.FloatArray()...) return }
/* * Compute an LU factorization of a general M-by-N matrix without pivoting. * * Arguments: * A On entry, the M-by-N matrix to be factored. On exit the factors * L and U from factorization A = P*L*U, the unit diagonal elements * of L are not stored. * * nb Blocking factor for blocked invocations. If bn == 0 or * min(M,N) < nb unblocked algorithm is used. * * Returns: * LU factorization and error indicator. * * Compatible with lapack.DGETRF */ func DecomposeLUnoPiv(A *matrix.FloatMatrix, nb int) (*matrix.FloatMatrix, error) { var err error mlen := imin(A.Rows(), A.Cols()) if mlen <= nb || nb == 0 { err = unblockedLUnoPiv(A) } else { err = blockedLUnoPiv(A, nb) } return A, err }
func sinv(x, y *matrix.FloatMatrix, dims *sets.DimensionSet, mnl int) (err error) { /*DEBUGGED*/ err = nil // For the nonlinear and 'l' blocks: // // yk o\ xk = yk .\ xk. ind := mnl + dims.At("l")[0] blas.Tbsv(y, x, &la_.IOpt{"n", ind}, &la_.IOpt{"k", 0}, &la_.IOpt{"ldA", 1}) // For the 'q' blocks: // // [ l0 -l1' ] // yk o\ xk = 1/a^2 * [ ] * xk // [ -l1 (a*I + l1*l1')/l0 ] // // where yk = (l0, l1) and a = l0^2 - l1'*l1. for _, m := range dims.At("q") { aa := blas.Nrm2Float(y, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offset", ind + 1}) ee := y.GetIndex(ind) aa = (ee + aa) * (ee - aa) cc := x.GetIndex(ind) dd := blas.DotFloat(x, y, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offsetx", ind + 1}, &la_.IOpt{"offsety", ind + 1}) x.SetIndex(ind, cc*ee-dd) blas.ScalFloat(x, aa/ee, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offset", ind + 1}) blas.AxpyFloat(y, x, dd/ee-cc, &la_.IOpt{"n", m - 1}, &la_.IOpt{"offsetx", ind + 1}, &la_.IOpt{"offsety", ind + 1}) blas.ScalFloat(x, 1.0/aa, &la_.IOpt{"n", m}, &la_.IOpt{"offset", ind}) ind += m } // For the 's' blocks: // // yk o\ xk = xk ./ gamma // // where gammaij = .5 * (yk_i + yk_j). ind2 := ind for _, m := range dims.At("s") { for j := 0; j < m; j++ { u := matrix.FloatVector(y.FloatArray()[ind2+j : ind2+m]) u.Add(y.GetIndex(ind2 + j)) u.Scale(0.5) blas.Tbsv(u, x, &la_.IOpt{"n", m - j}, &la_.IOpt{"k", 0}, &la_.IOpt{"lda", 1}, &la_.IOpt{"offsetx", ind + j*(m+1)}) } ind += m * m ind2 += m } return }
/* Returns sqrt(x' * J * x) where J = [1, 0; 0, -I], for a vector x in a second order cone. */ func jnrm2(x *matrix.FloatMatrix, n, offset int) float64 { /*DEBUGGED*/ if n <= 0 { n = x.NumElements() } if offset < 0 { offset = 0 } a := blas.Nrm2Float(x, &la_.IOpt{"n", n - 1}, &la_.IOpt{"offset", offset + 1}) fst := x.GetIndex(offset) return math.Sqrt(fst-a) * math.Sqrt(fst+a) }
// See function Scal. func ScalFloat(X *matrix.FloatMatrix, alpha float64, 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 } Xa := X.FloatArray() dscal(ind.Nx, alpha, Xa[ind.OffsetX:], ind.IncX) return }
func saveData(A *matrix.FloatMatrix) { var fd *os.File if fileName == "" { fileName = testName + ".dat" } fd, err := os.Create(fileName) if err != nil { fmt.Fprintf(os.Stderr, "create error: %v\n", err) return } io.WriteString(fd, A.ToString("%14e")) fd.Close() }
/* * ( A11 a12 ) ( U11 u12 )( D1 0 )( U11.t 0 ) * ( a21 a22 ) ( 0 1 )( 0 d2 )( u12.t 1 ) * * a22 = d2 * a01 = u12*d2 => u12 = a12/d2 * A11 = u12*d2*u12.t + U11*D1*U11.t => U11 = A11 - u12*d2*u12.t */ func unblkUpperLDLnoPiv(A *matrix.FloatMatrix) (err error) { var ATL, ATR, ABL, ABR matrix.FloatMatrix var A00, a01, A02, a11, a12, A22 matrix.FloatMatrix err = nil partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, pBOTTOMRIGHT) for ATL.Rows() > 0 { repartition2x2to3x3(&ATL, &A00, &a01, &A02, nil, &a11, &a12, nil, nil, &A22, A, 1, pTOPLEFT) // -------------------------------------------------------- // A00 = A00 - u01*d11*u01.T = A00 - a01*a01.T/a11; triangular update err = MVUpdateTrm(&A00, &a01, &a01, -1.0/a11.Float(), UPPER) // u01 = a01/a11 InvScale(&a01, a11.Float()) // --------------------------------------------------------- continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, pTOPLEFT) } return }
func createGpProg(K []int, F, g *matrix.FloatMatrix) *gpConvexProg { gp := &gpConvexProg{mnl: len(K) - 1, l: F.Rows(), n: F.Cols()} gp.ind = make([][2]int, len(K)) s := 0 for i := 0; i < len(K); i++ { gp.ind[i][0] = s gp.ind[i][1] = s + K[i] s += K[i] } gp.F = F gp.g = g gp.maxK = maxdim(K) return gp }
/* From LAPACK/dlarfg.f * * DLARFG generates a real elementary reflector H of order n, such * that * * H * ( alpha ) = ( beta ), H**T * H = I. * ( x ) ( 0 ) * * where alpha and beta are scalars, and x is an (n-1)-element real * vector. H is represented in the form * * H = I - tau * ( 1 ) * ( 1 v**T ) , * ( v ) * * where tau is a real scalar and v is a real (n-1)-element * vector. * * If the elements of x are all zero, then tau = 0 and H is taken to be * the unit matrix. * * Otherwise 1 <= tau <= 2. */ func computeHouseholder(a11, x, tau *matrix.FloatMatrix, flags Flags) { // norm_x2 = ||x||_2 norm_x2 := Norm2(x) if norm_x2 == 0.0 { //a11.SetAt(0, 0, -a11.GetAt(0, 0)) tau.SetAt(0, 0, 0.0) return } alpha := a11.GetAt(0, 0) sign := 1.0 if math.Signbit(alpha) { sign = -1.0 } // beta = -(alpha / |alpha|) * ||alpha x|| // = -sign(alpha) * sqrt(alpha**2, norm_x2**2) beta := -sign * sqrtX2Y2(alpha, norm_x2) // x = x /(a11 - beta) InvScale(x, alpha-beta) tau.SetAt(0, 0, (beta-alpha)/beta) a11.SetAt(0, 0, beta) }
func solveMVTest(t *testing.T, A, X0 *matrix.FloatMatrix, flags Flags, bN, bNB int) { X1 := X0.Copy() uplo := linalg.OptUpper diag := linalg.OptNonUnit if flags&LOWER != 0 { uplo = linalg.OptLower } if flags&UNIT != 0 { diag = linalg.OptUnit } blas.TrsvFloat(A, X0, uplo, diag) Ar := A.FloatArray() Xr := X1.FloatArray() if bN == bNB { DSolveUnblkMV(Xr, Ar, flags, 1, A.LeadingIndex(), bN) } else { DSolveBlkMV(Xr, Ar, flags, 1, A.LeadingIndex(), bN, bNB) } ok := X1.AllClose(X0) t.Logf("X1 == X0: %v\n", ok) if !ok && bN < 8 { t.Logf("A=\n%v\n", A) t.Logf("X0=\n%v\n", X0) t.Logf("blas: X0\n%v\n", X0) t.Logf("X1:\n%v\n", X1) } }
// unblocked LU decomposition w/o pivots, FLAME LU nopivots variant 5 func unblockedLUnoPiv(A *matrix.FloatMatrix) (err error) { var ATL, ATR, ABL, ABR matrix.FloatMatrix var A00, a01, A02, a10, a11, a12, A20, a21, A22 matrix.FloatMatrix err = nil partition2x2( &ATL, &ATR, &ABL, &ABR, A, 0, 0, pTOPLEFT) for ATL.Rows() < A.Rows() { repartition2x2to3x3(&ATL, &A00, &a01, &A02, &a10, &a11, &a12, &A20, &a21, &A22, A, 1, pBOTTOMRIGHT) // a21 = a21/a11 //a21.Scale(1.0/a11.Float()) InvScale(&a21, a11.Float()) // A22 = A22 - a21*a12 err = MVRankUpdate(&A22, &a21, &a12, -1.0) continue3x3to2x2( &ATL, &ATR, &ABL, &ABR, &A00, &a11, &A22, A, pBOTTOMRIGHT) } return }