func CompareJac(tst *testing.T, ffcn Cb_f, Jfcn Cb_J, x []float64, tol float64, distr bool) { n := len(x) // numerical fx := make([]float64, n) w := make([]float64, n) // workspace ffcn(fx, x) var Jnum la.Triplet Jnum.Init(n, n, n*n) Jacobian(&Jnum, ffcn, x, fx, w, distr) jn := Jnum.ToMatrix(nil) // analytical var Jana la.Triplet Jana.Init(n, n, n*n) Jfcn(&Jana, x) ja := Jana.ToMatrix(nil) // compare //la.PrintMat(fmt.Sprintf("Jana(%d)",mpi.Rank()), ja.ToDense(), "%13.6f", false) //la.PrintMat(fmt.Sprintf("Jnum(%d)",mpi.Rank()), jn.ToDense(), "%13.6f", false) max_diff := la.MatMaxDiff(jn.ToDense(), ja.ToDense()) if max_diff > tol { tst.Errorf("[1;31mmax_diff = %g[0m\n", max_diff) } else { io.Pf("[1;32mmax_diff = %g[0m\n", max_diff) } }
// CompareJacMpi compares Jacobian matrix (e.g. for testing) func CompareJacMpi(tst *testing.T, ffcn Cb_f, Jfcn Cb_J, x []float64, tol float64, distr bool) { // numerical n := len(x) fx := make([]float64, n) w := make([]float64, n) // workspace ffcn(fx, x) var Jnum la.Triplet Jnum.Init(n, n, n*n) JacobianMpi(&Jnum, ffcn, x, fx, w, distr) jn := Jnum.ToMatrix(nil) // analytical var Jana la.Triplet Jana.Init(n, n, n*n) Jfcn(&Jana, x) ja := Jana.ToMatrix(nil) // compare max_diff := la.MatMaxDiff(jn.ToDense(), ja.ToDense()) if max_diff > tol { tst.Errorf("[1;31mmax_diff = %g[0m\n", max_diff) } else { io.Pf("[1;32mmax_diff = %g[0m\n", max_diff) } }
// CheckJ check Jacobian matrix // Ouptut: cnd -- condition number (with Frobenius norm) func (o *NlSolver) CheckJ(x []float64, tol float64, chkJnum, silent bool) (cnd float64, err error) { // Jacobian matrix var Jmat [][]float64 if o.useDn { Jmat = la.MatAlloc(o.neq, o.neq) err = o.JfcnDn(Jmat, x) if err != nil { return 0, chk.Err(_nls_err5, "dense", err.Error()) } } else { if o.numJ { err = Jacobian(&o.Jtri, o.Ffcn, x, o.fx, o.w, false) if err != nil { return 0, chk.Err(_nls_err5, "sparse", err.Error()) } } else { err = o.JfcnSp(&o.Jtri, x) if err != nil { return 0, chk.Err(_nls_err5, "sparse(num)", err.Error()) } } Jmat = o.Jtri.ToMatrix(nil).ToDense() } //la.PrintMat("J", Jmat, "%23g", false) // condition number cnd, err = la.MatCondG(Jmat, "F", 1e-10) if err != nil { return cnd, chk.Err(_nls_err6, err.Error()) } if math.IsInf(cnd, 0) || math.IsNaN(cnd) { return cnd, chk.Err(_nls_err7, cnd) } // numerical Jacobian if !chkJnum { return } var Jtmp la.Triplet ws := make([]float64, o.neq) err = o.Ffcn(o.fx, x) if err != nil { return } Jtmp.Init(o.neq, o.neq, o.neq*o.neq) Jacobian(&Jtmp, o.Ffcn, x, o.fx, ws, false) Jnum := Jtmp.ToMatrix(nil).ToDense() for i := 0; i < o.neq; i++ { for j := 0; j < o.neq; j++ { chk.PrintAnaNum(io.Sf("J[%d][%d]", i, j), tol, Jmat[i][j], Jnum[i][j], !silent) } } maxdiff := la.MatMaxDiff(Jmat, Jnum) if maxdiff > tol { err = chk.Err(_nls_err8, maxdiff) } return }