func Test_dist_lognormal_01(tst *testing.T) { //verbose() chk.PrintTitle("dist_lognormal_01") _, dat, err := io.ReadTable("data/lognormal.dat") if err != nil { tst.Errorf("cannot read comparison results:\n%v\n", err) return } X, ok := dat["x"] if !ok { tst.Errorf("cannot get x values\n") return } N, ok := dat["n"] if !ok { tst.Errorf("cannot get n values\n") return } Z, ok := dat["z"] if !ok { tst.Errorf("cannot get z values\n") return } YpdfCmp, ok := dat["ypdf"] if !ok { tst.Errorf("cannot get ypdf values\n") return } YcdfCmp, ok := dat["ycdf"] if !ok { tst.Errorf("cannot get ycdf values\n") return } var dist DistLogNormal nx := len(X) for i := 0; i < nx; i++ { w := Z[i] * Z[i] μ := math.Exp(N[i] + w/2.0) σ := μ * math.Sqrt(math.Exp(w)-1.0) dist.Init(&VarData{M: μ, S: σ}) Ypdf := dist.Pdf(X[i]) Ycdf := dist.Cdf(X[i]) err := chk.PrintAnaNum("ypdf", 1e-14, YpdfCmp[i], Ypdf, chk.Verbose) if err != nil { tst.Errorf("pdf failed: %v\n", err) return } err = chk.PrintAnaNum("ycdf", 1e-15, YcdfCmp[i], Ycdf, chk.Verbose) if err != nil { tst.Errorf("cdf failed: %v\n", err) return } } }
func Test_dist_gumbel_01(tst *testing.T) { //verbose() chk.PrintTitle("dist_gumbel_01") _, dat, err := io.ReadTable("data/gumbel.dat") if err != nil { tst.Errorf("cannot read comparison results:\n%v\n", err) return } X, ok := dat["x"] if !ok { tst.Errorf("cannot get x values\n") return } U, ok := dat["u"] if !ok { tst.Errorf("cannot get u values\n") return } B, ok := dat["b"] if !ok { tst.Errorf("cannot get b values\n") return } YpdfCmp, ok := dat["ypdf"] if !ok { tst.Errorf("cannot get ypdf values\n") return } YcdfCmp, ok := dat["ycdf"] if !ok { tst.Errorf("cannot get ycdf values\n") return } var dist DistGumbel nx := len(X) for i := 0; i < nx; i++ { dist.U = U[i] dist.B = B[i] Ypdf := dist.Pdf(X[i]) Ycdf := dist.Cdf(X[i]) err := chk.PrintAnaNum("ypdf", 1e-14, YpdfCmp[i], Ypdf, chk.Verbose) if err != nil { tst.Errorf("pdf failed: %v\n", err) return } err = chk.PrintAnaNum("ycdf", 1e-15, YcdfCmp[i], Ycdf, chk.Verbose) if err != nil { tst.Errorf("cdf failed: %v\n", err) return } } }
func Test_norm01(tst *testing.T) { //verbose() chk.PrintTitle("norm01") _, dat, err := io.ReadTable("data/normal.dat") if err != nil { tst.Errorf("cannot read comparison results:\n%v\n", err) return } X, ok := dat["x"] if !ok { tst.Errorf("cannot get x values\n") return } Mu, ok := dat["mu"] if !ok { tst.Errorf("cannot get mu values\n") return } Sig, ok := dat["sig"] if !ok { tst.Errorf("cannot get sig values\n") return } YpdfCmp, ok := dat["ypdf"] if !ok { tst.Errorf("cannot get ypdf values\n") return } YcdfCmp, ok := dat["ycdf"] if !ok { tst.Errorf("cannot get ycdf values\n") return } var dist DistNormal n := len(X) for i := 0; i < n; i++ { dist.Init(&VarData{M: Mu[i], S: Sig[i]}) Ypdf := dist.Pdf(X[i]) Ycdf := dist.Cdf(X[i]) err := chk.PrintAnaNum("ypdf", 1e-15, YpdfCmp[i], Ypdf, chk.Verbose) if err != nil { tst.Errorf("pdf failed: %v\n", err) return } err = chk.PrintAnaNum("ycdf", 1e-15, YcdfCmp[i], Ycdf, chk.Verbose) if err != nil { tst.Errorf("cdf failed: %v\n", err) return } } }
func Test_dist_uniform_01(tst *testing.T) { //verbose() chk.PrintTitle("dist_uniform_01") _, dat, err := io.ReadTable("data/uniform.dat") if err != nil { tst.Errorf("cannot read comparison results:\n%v\n", err) return } X, ok := dat["x"] if !ok { tst.Errorf("cannot get x values\n") return } A, ok := dat["a"] // min if !ok { tst.Errorf("cannot get a values\n") return } B, ok := dat["b"] // max if !ok { tst.Errorf("cannot get b values\n") return } YpdfCmp, ok := dat["ypdf"] if !ok { tst.Errorf("cannot get ypdf values\n") return } YcdfCmp, ok := dat["ycdf"] if !ok { tst.Errorf("cannot get ycdf values\n") return } var dist DistUniform nx := len(X) for i := 0; i < nx; i++ { dist.Init(&VarData{Min: A[i], Max: B[i]}) Ypdf := dist.Pdf(X[i]) Ycdf := dist.Cdf(X[i]) err := chk.PrintAnaNum("ypdf", 1e-14, YpdfCmp[i], Ypdf, chk.Verbose) if err != nil { tst.Errorf("pdf failed: %v\n", err) return } err = chk.PrintAnaNum("ycdf", 1e-15, YcdfCmp[i], Ycdf, chk.Verbose) if err != nil { tst.Errorf("cdf failed: %v\n", err) return } } }
// 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 }
func main() { // define function and derivative function y_fcn := func(x float64) float64 { return math.Sin(x) } dydx_fcn := func(x float64) float64 { return math.Cos(x) } d2ydx2_fcn := func(x float64) float64 { return -math.Sin(x) } // run test for 11 points X := utl.LinSpace(0, 2*math.Pi, 11) io.Pf(" %8s %23s %23s %23s\n", "x", "analytical", "numerical", "error") for _, x := range X { // analytical derivatives dydx_ana := dydx_fcn(x) d2ydx2_ana := d2ydx2_fcn(x) // numerical derivative: dydx dydx_num, _ := num.DerivCentral(func(t float64, args ...interface{}) float64 { return y_fcn(t) }, x, 1e-3) // numerical derivative d2ydx2 d2ydx2_num, _ := num.DerivCentral(func(t float64, args ...interface{}) float64 { return dydx_fcn(t) }, x, 1e-3) // check chk.PrintAnaNum(io.Sf("dy/dx @ %.6f", x), 1e-10, dydx_ana, dydx_num, true) chk.PrintAnaNum(io.Sf("d²y/dx² @ %.6f", x), 1e-10, d2ydx2_ana, d2ydx2_num, true) } // generate 101 points for plotting X = utl.LinSpace(0, 2*math.Pi, 101) Y := make([]float64, len(X)) for i, x := range X { Y[i] = y_fcn(x) } // plot plt.SetForPng(0.75, 300, 150) plt.Plot(X, Y, "'b.-', clip_on=0, markevery=10, label='y(x)=sin(x)'") plt.Gll("x", "y", "") plt.SaveD("/tmp/gosl", "num_deriv01.png") }
func main() { // define function and derivative function y_fcn := func(x float64) float64 { return math.Sin(x) } dydx_fcn := func(x float64) float64 { return math.Cos(x) } d2ydx2_fcn := func(x float64) float64 { return -math.Sin(x) } // run test for 11 points X := utl.LinSpace(0, 2*math.Pi, 11) for _, x := range X { // analytical derivatives dydx_ana := dydx_fcn(x) d2ydx2_ana := d2ydx2_fcn(x) // numerical derivative: dydx dydx_num, _ := num.DerivCentral(func(t float64, args ...interface{}) float64 { return y_fcn(t) }, x, 1e-3) // numerical derivative d2ydx2 d2ydx2_num, _ := num.DerivCentral(func(t float64, args ...interface{}) float64 { return dydx_fcn(t) }, x, 1e-3) // check chk.PrintAnaNum(io.Sf("dy/dx @ %.6f", x), 1e-10, dydx_ana, dydx_num, true) chk.PrintAnaNum(io.Sf("d²y/dx² @ %.6f", x), 1e-10, d2ydx2_ana, d2ydx2_num, true) } // generate 101 points X = utl.LinSpace(0, 2*math.Pi, 101) Y := make([]float64, len(X)) for i, x := range X { Y[i] = y_fcn(x) } // plot plt.Plot(X, Y, "'b.-'") plt.Gll("x", "y", "") plt.Show() }
// CompareStress compares stresses // Output: // e -- L² error for each component func (o *PlateHole) CompareStress(t float64, x, σ []float64, tol float64, verbose bool) (e []float64) { // analytical solution sx, sy, sz, sxy := o.Stress(t, x) // message if verbose { chk.PrintAnaNum("σx ", tol, sx, σ[0], verbose) chk.PrintAnaNum("σy ", tol, sy, σ[1], verbose) chk.PrintAnaNum("σz ", tol, sz, σ[2], verbose) chk.PrintAnaNum("σxy", tol, sxy, σ[3], verbose) } // check stresses e = []float64{ math.Abs(sx - σ[0]), math.Abs(sy - σ[1]), math.Abs(sz - σ[2]), math.Abs(sxy - σ[3]), } return }
// CheckEigenprojsDerivs checks the derivatives of eigen projectors w.r.t defining tensor func CheckEigenprojsDerivs(a []float64, tol float64, ver bool, zero float64) { // compute eigenvalues and eigenprojectors ncp := len(a) λ := make([]float64, 3) P := la.MatAlloc(3, ncp) docalc := func() { err := M_EigenValsProjsNum(P, λ, a) if err != nil { chk.Panic("eigenprojs.go: CheckEigenprojsDerivs failed:\n %v", err.Error()) } } // compute derivatives of eigenprojectors docalc() dPda := utl.Deep3alloc(3, ncp, ncp) err := M_EigenProjsDerivAuto(dPda, a, λ, P) if err != nil { chk.Panic("%v", err) } // check var tmp float64 has_error := false for k := 0; k < 3; k++ { for i := 0; i < ncp; i++ { for j := 0; j < ncp; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, a[j] = a[j], x docalc() a[j] = tmp return P[k][i] }, a[j], 1e-6) err := chk.PrintAnaNum(io.Sf("dP%d[%d]/da[%d]", k, i, j), tol, dPda[k][i][j], dnum, ver) if err != nil { has_error = true } } } if ver { io.Pf("\n") } } if has_error { chk.Panic(_eigenprojs_err8) } return }
// Run runs simulation func (o *Driver) Run(pth *Path) (err error) { // specialised models var sml Small var eup SmallStrainUpdater switch m := o.model.(type) { case Small: sml = m case SmallStrainUpdater: eup = m default: return chk.Err("cannot handle large-deformation models yet\n") } // elastoplastic model epm := o.model.(EPmodel) // initial stresses σ0 := make([]float64, o.nsig) σ0[0] = pth.MultS * pth.Sx[0] σ0[1] = pth.MultS * pth.Sy[0] σ0[2] = pth.MultS * pth.Sz[0] // allocate results arrays nr := 1 + (pth.Size()-1)*pth.Nincs if nr < 2 { return chk.Err(_driver_err04, pth.Size(), pth.Nincs) } o.Res = make([]*State, nr) o.Eps = la.MatAlloc(nr, o.nsig) for i := 0; i < nr; i++ { o.Res[i], err = o.model.InitIntVars(σ0) if err != nil { return } } // put initial stress in predictor-corrector array o.PreCor = [][]float64{o.Res[0].Sig} // auxiliary variables Δσ := make([]float64, o.nsig) Δε := make([]float64, o.nsig) // variables for checking D var tmp float64 var εold, εnew, Δεtmp []float64 var stmp *State derivfcn := num.DerivCen if o.CheckD { εold = make([]float64, o.nsig) εnew = make([]float64, o.nsig) Δεtmp = make([]float64, o.nsig) stmp, err = o.model.InitIntVars(σ0) if err != nil { return } if o.UseDfwd { derivfcn = num.DerivFwd } } // update states k := 1 for i := 1; i < pth.Size(); i++ { // stress path if pth.UseS[i] > 0 { return chk.Err("cannot run StrainUpdate for stress paths at the moment") Δσ[0] = pth.MultS * (pth.Sx[i] - pth.Sx[i-1]) / float64(pth.Nincs) Δσ[1] = pth.MultS * (pth.Sy[i] - pth.Sy[i-1]) / float64(pth.Nincs) Δσ[2] = pth.MultS * (pth.Sz[i] - pth.Sz[i-1]) / float64(pth.Nincs) for inc := 0; inc < pth.Nincs; inc++ { // update o.Res[k].Set(o.Res[k-1]) copy(o.Eps[k], o.Eps[k-1]) if eup != nil { err = eup.StrainUpdate(o.Res[k], Δσ) } if err != nil { if !o.Silent { io.Pfred(_driver_err01, err) } return } k += 1 } } // strain path if pth.UseE[i] > 0 { Δε[0] = pth.MultE * (pth.Ex[i] - pth.Ex[i-1]) / float64(pth.Nincs) Δε[1] = pth.MultE * (pth.Ey[i] - pth.Ey[i-1]) / float64(pth.Nincs) Δε[2] = pth.MultE * (pth.Ez[i] - pth.Ez[i-1]) / float64(pth.Nincs) for inc := 0; inc < pth.Nincs; inc++ { // update strains la.VecAdd2(o.Eps[k], 1, o.Eps[k-1], 1, Δε) // εnew = εold + Δε // update stresses o.Res[k].Set(o.Res[k-1]) err = sml.Update(o.Res[k], o.Eps[k], Δε, 0, 0) if err != nil { if !o.Silent { io.Pfred(_driver_err02, err) } return } if epm != nil { tmp := o.Res[k-1].GetCopy() //s0 := make([]float64, o.nsig) //_, p0, q0 := tsr.M_devσ(s0, o.Res[k-1].Sig) //io.Pfblue2("p=%v q=%v\n", p0, q0) epm.ElastUpdate(tmp, o.Eps[k]) o.PreCor = append(o.PreCor, tmp.Sig, o.Res[k].Sig) } // check consistent matrix if o.CheckD { firstIt := false err = sml.CalcD(o.D, o.Res[k], firstIt) if err != nil { return chk.Err(_driver_err03, err) } copy(εold, o.Eps[k-1]) copy(εnew, o.Eps[k]) has_error := false if o.VerD { io.Pf("\n") } for i := 0; i < o.nsig; i++ { for j := 0; j < o.nsig; j++ { dnum := derivfcn(func(x float64, args ...interface{}) (res float64) { tmp, εnew[j] = εnew[j], x for l := 0; l < o.nsig; l++ { Δεtmp[l] = εnew[l] - εold[l] } stmp.Set(o.Res[k-1]) err = sml.Update(stmp, εnew, Δεtmp, 0, 0) if err != nil { chk.Panic("cannot run Update for numerical derivative: %v", err) } res, εnew[j] = stmp.Sig[i], tmp return }, εnew[j]) err := chk.PrintAnaNum(io.Sf("D[%d][%d]", i, j), o.TolD, o.D[i][j], dnum, o.VerD) if err != nil { has_error = true } } } if has_error { return chk.Err(_driver_err03, "ana-num comparison failed\n") } } k += 1 } } } return }
// CheckDerivs check derivatives computed by isotropic function func (o *IsoFun) CheckDerivs(A []float64, tol, tol2, tolq, tol3 float64, ver bool, args ...interface{}) (err error) { // L and invariants chk.IntAssert(len(A), o.ncp) L := make([]float64, 3) err = M_EigenValsNum(L, A) if err != nil { return } p, q, err := GenInvs(L, o.n, o.a) if err != nil { return } io.Pforan("L = %v\n", L) io.Pforan("p, q = %v, %v\n", p, q) // constants h := 1e-6 var has_error error // derivatives of callback functions /////////////// // df/dp, df/dq, d²f/dp², d²f/dq², d²f/dpdq dfdp, dfdq := o.gfcn(p, q, args...) d2fdp2, d2fdq2, d2fdpdq := o.hfcn(p, q, args...) if ver { io.Pfpink("\nd w.r.t invariants . . . \n") } // check df/dp dfdp_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { return o.ffcn(x, q, args...) }, p, h) err = chk.PrintAnaNum("df/dp ", tol, dfdp, dfdp_num, ver) if err != nil { has_error = err } // check df/dq dfdq_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { return o.ffcn(p, x, args...) }, q, h) err = chk.PrintAnaNum("df/dq ", tol, dfdq, dfdq_num, ver) if err != nil { has_error = err } // check d²f/dp² d2fdp2_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { dfdp_tmp, _ := o.gfcn(x, q, args...) return dfdp_tmp }, p, h) err = chk.PrintAnaNum("d²f/dp² ", tol, d2fdp2, d2fdp2_num, ver) if err != nil { has_error = err } // check d²f/dq² d2fdq2_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { _, dfdq_tmp := o.gfcn(p, x, args...) return dfdq_tmp }, q, h) err = chk.PrintAnaNum("d²f/dq² ", tol, d2fdq2, d2fdq2_num, ver) if err != nil { has_error = err } // check d²f/dpdq d2fdpdq_num, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { dfdp_tmp, _ := o.gfcn(p, x, args...) return dfdp_tmp }, q, h) err = chk.PrintAnaNum("d²f/dpdq", tol, d2fdpdq, d2fdpdq_num, ver) if err != nil { has_error = err } // derivatives w.r.t eigenvalues /////////////////// // df/dL and d²f/dLdL _, err = o.Gp(L, args...) if err != nil { chk.Panic("Gp failed:\n%v", err) } err = o.HafterGp(args...) if err != nil { chk.Panic("HafterGp failed:\n%v", err) } dfdL := make([]float64, 3) d2pdLdL := la.MatAlloc(3, 3) d2qdLdL := la.MatAlloc(3, 3) d2fdLdL := la.MatAlloc(3, 3) copy(dfdL, o.DfdL) la.MatCopy(d2pdLdL, 1, o.d2pdLdL) la.MatCopy(d2qdLdL, 1, o.d2qdLdL) la.MatCopy(d2fdLdL, 1, o.DgdL) // check df/dL if ver { io.Pfpink("\ndf/dL . . . . . . . . \n") } var fval, tmp float64 for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { tmp, L[j] = L[j], x defer func() { L[j] = tmp }() fval, err = o.Fp(L, args...) if err != nil { chk.Panic("Fp failed:\n%v", err) } return fval }, L[j], h) err := chk.PrintAnaNum(io.Sf("df/dL[%d]", j), tol, dfdL[j], dnum, ver) if err != nil { has_error = err } } // check d²p/dLdL if ver { io.Pfpink("\nd²p/dLdL . . . . . . . . \n") } for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { tmp, L[j] = L[j], x defer func() { L[j] = tmp }() _, err = o.Gp(L, args...) if err != nil { chk.Panic("Gp failed\n%v", err) } return o.dpdL[i] }, L[j], h) err := chk.PrintAnaNum(io.Sf("d²p/dL[%d]dL[%d]", i, j), tol2, d2pdLdL[i][j], dnum, ver) if err != nil { has_error = err } } } // check d²q/dLdL if ver { io.Pfpink("\nd²q/dLdL . . . . . . . . \n") } for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { tmp, L[j] = L[j], x defer func() { L[j] = tmp }() _, err = o.Gp(L, args...) if err != nil { chk.Panic("Gp failed\n%v", err) } return o.dqdL[i] }, L[j], h) err := chk.PrintAnaNum(io.Sf("d²q/dL[%d]dL[%d]", i, j), tolq, d2qdLdL[i][j], dnum, ver) if err != nil { has_error = err } } } // check d²f/dLdL if ver { io.Pfpink("\nd²f/dLdL . . . . . . . . \n") } for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { tmp, L[j] = L[j], x defer func() { L[j] = tmp }() _, err = o.Gp(L, args...) if err != nil { chk.Panic("Gp failed\n%v", err) } return o.DfdL[i] }, L[j], h) err := chk.PrintAnaNum(io.Sf("d²f/dL[%d]dL[%d]", i, j), tol2, d2fdLdL[i][j], dnum, ver) if err != nil { has_error = err } } } // derivatives w.r.t full tensor /////////////////// // dfdA and d²f/dAdA ncp := len(A) dfdA := make([]float64, ncp) d2fdAdA := la.MatAlloc(ncp, ncp) _, err = o.Ga(dfdA, A, args...) // also computes P, L and Acpy if err != nil { chk.Panic("Ga failed:\n%v", err) } err = o.HafterGa(d2fdAdA, args...) // also computes dPdA if err != nil { chk.Panic("HafterGa failed:\n%v", err) } // check df/dA if ver { io.Pfpink("\ndf/dA . . . . . . . . \n") } for j := 0; j < ncp; j++ { dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { tmp, A[j] = A[j], x defer func() { A[j] = tmp }() fval, err = o.Fa(A, args...) if err != nil { chk.Panic("Fa failed:\n%v", err) } return fval }, A[j], h) err := chk.PrintAnaNum(io.Sf("df/dA[%d]", j), tol, dfdA[j], dnum, ver) if err != nil { has_error = err } } // check dP/dA if false { for k := 0; k < 3; k++ { if ver { io.Pfpink("\ndP%d/dA . . . . . . . . \n", k) } for i := 0; i < ncp; i++ { for j := 0; j < ncp; j++ { dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { tmp, A[j] = A[j], x defer func() { A[j] = tmp }() err = M_EigenValsProjsNum(o.P, o.L, o.Acpy) if err != nil { chk.Panic("M_EigenValsProjsNum failed:\n%v", err) } return o.P[k][i] }, A[j], h) err := chk.PrintAnaNum(io.Sf("dP%d/dA[%d]dA[%d]", k, i, j), tol, o.dPdA[k][i][j], dnum, ver) if err != nil { has_error = err } } } } } // check d²f/dAdA if ver { io.Pfpink("\nd²f/dAdA . . . . . . . . \n") } dfdA_tmp := make([]float64, ncp) for i := 0; i < ncp; i++ { for j := 0; j < ncp; j++ { dnum, _ := num.DerivCentral(func(x float64, notused ...interface{}) (res float64) { tmp, A[j] = A[j], x defer func() { A[j] = tmp }() _, err = o.Ga(dfdA_tmp, A, args...) if err != nil { chk.Panic("Ga failed:\n%v", err) } return dfdA_tmp[i] }, A[j], h) dtol := tol2 if i == j && (i == 3 || i == 4 || i == 5) { dtol = tol3 } err := chk.PrintAnaNum(io.Sf("d²f/dA[%d]dA[%d]", i, j), dtol, d2fdAdA[i][j], dnum, ver) if err != nil { has_error = err } } } // any errors? if has_error != nil { err = has_error } return }
// Run runs simulation func (o *Driver) Run(Pc []float64) (err error) { // allocate results arrays np := len(Pc) o.Res = make([]*State, np) // initialise first state o.Res[0], err = o.Mdl.NewState(o.Mdl.RhoL0, o.Mdl.RhoG0, -Pc[0], 0) if err != nil { return } // auxiliary derivfcn := num.DerivCen if o.UseDfwd { derivfcn = num.DerivFwd } // update states var pcOld, pcNew, Δpc, tmp, Ccb, Ccbtmp, Ccd float64 var stmp State for i := 1; i < np; i++ { // increment pcOld = Pc[i-1] pcNew = Pc[i] Δpc = pcNew - pcOld // update o.Res[i] = o.Res[i-1].GetCopy() err = o.Mdl.Update(o.Res[i], -Δpc, 0, -pcNew, 0) if err != nil { return } // check consistent moduli if o.CheckD { // check Ccb Ccb, err = o.Mdl.Ccb(o.Res[i], pcNew) if err != nil { return } var has_errors bool dnum := derivfcn(func(x float64, args ...interface{}) (res float64) { tmp, pcNew = pcNew, x Δpc = pcNew - pcOld stmp.Set(o.Res[i-1]) e := o.Mdl.Update(&stmp, -Δpc, 0, -pcNew, 0) if e != nil { has_errors = true } res, pcNew = stmp.A_sl, tmp return }, pcNew) if has_errors { return chk.Err("problems arised during update in numerical derivative for Ccb") } err = chk.PrintAnaNum(io.Sf("Ccb @ %.3f,%.4f", pcNew, o.Res[i].A_sl), o.TolCcb, Ccb, dnum, o.VerD) if err != nil { return } // check Ccd Ccd, err = o.Mdl.Ccd(o.Res[i], pcNew) if err != nil { return } has_errors = false dnum = derivfcn(func(x float64, args ...interface{}) (res float64) { tmp, pcNew = pcNew, x Δpc = pcNew - pcOld stmp.Set(o.Res[i-1]) e := o.Mdl.Update(&stmp, -Δpc, 0, -pcNew, 0) if e != nil { has_errors = true } Ccbtmp, _ = o.Mdl.Ccb(&stmp, pcNew) res, pcNew = Ccbtmp, tmp return }, pcNew) if has_errors { return chk.Err("problems arised during update in numerical derivative for Ccd") } err = chk.PrintAnaNum(io.Sf("Ccd @ %.3f,%.4f", pcNew, o.Res[i].A_sl), o.TolCcd, Ccd, dnum, o.VerD) if err != nil { return } } } return }
func Test_bspline03(tst *testing.T) { //verbose() chk.PrintTitle("bspline03") // 0 1 2 3 4 5 6 7 8 9 10 T := []float64{0, 0, 0, 1, 2, 3, 4, 4, 5, 5, 5} var s Bspline s.Init(T, 2) s.SetControl([][]float64{{0, 0}, {0.5, 1}, {1, 0}, {1.5, 0}, {2, 1}, {2.5, 1}, {3, 0.5}, {3.5, 0}}) // analytical derivatives s.CalcBasisAndDerivs(3.99) io.Pfpink("ana: dNdt(t=3.99, i=5) = %v\n", s.GetDeriv(5)) io.Pfpink("ana: dNdt(t=3.99, i=6) = %v\n", s.GetDeriv(6)) io.Pfpink("ana: dNdt(t=3.99, i=7) = %v\n", s.GetDeriv(7)) s.CalcBasisAndDerivs(4.0) io.Pforan("ana: dNdt(t=4.00, i=5) = %v\n", s.GetDeriv(5)) io.Pforan("ana: dNdt(t=4.00, i=6) = %v\n", s.GetDeriv(6)) io.Pforan("ana: dNdt(t=4.00, i=7) = %v\n", s.GetDeriv(7)) // numerical derivatives io.Pfcyan("num: dNdt(t=3.99, i=5) = %v\n", s.NumericalDeriv(3.99, 5)) io.Pfcyan("num: dNdt(t=3.99, i=6) = %v\n", s.NumericalDeriv(3.99, 6)) io.Pfcyan("num: dNdt(t=3.99, i=7) = %v\n", s.NumericalDeriv(3.99, 7)) io.Pfblue2("num: dNdt(t=4.00, i=5) = %v\n", s.NumericalDeriv(4.00, 5)) io.Pfblue2("num: dNdt(t=4.00, i=6) = %v\n", s.NumericalDeriv(4.00, 6)) io.Pfblue2("num: dNdt(t=4.00, i=7) = %v\n", s.NumericalDeriv(4.00, 7)) ver := false tol := 1e-5 tt := utl.LinSpace(0, 5, 11) numd := make([]float64, s.NumBasis()) anad := make([]float64, s.NumBasis()) for _, t := range tt { for i := 0; i < s.NumBasis(); i++ { s.CalcBasisAndDerivs(t) anad[i] = s.GetDeriv(i) numd[i] = s.NumericalDeriv(t, i) // numerical fails @ 4 [4,5,6] if t == 4 { numd[4] = anad[4] numd[5] = anad[5] numd[6] = anad[6] } chk.PrintAnaNum(io.Sf("i=%d t=%v", i, t), tol, anad[i], numd[i], ver) } chk.Vector(tst, io.Sf("derivs @ %v", t), tol, numd, anad) } if chk.Verbose { npts := 201 plt.SetForPng(1.5, 600, 150) plt.SplotGap(0, 0.3) str0 := ",lw=2" str1 := ",ls='none',marker='+',color='cyan',markevery=10" str2 := ",ls='none',marker='x',markevery=10" str3 := ",ls='none',marker='+',markevery=10" str4 := ",ls='none',marker='4',markevery=10" plt.Subplot(3, 1, 1) s.Draw2d(str0, "", npts, 0) // 0 => CalcBasis s.Draw2d(str1, "", npts, 1) // 1 => RecursiveBasis plt.Subplot(3, 1, 2) s.PlotBasis("", npts, 0) // 0 => CalcBasis s.PlotBasis(str2, npts, 1) // 1 => CalcBasisAndDerivs s.PlotBasis(str3, npts, 2) // 2 => RecursiveBasis plt.Subplot(3, 1, 3) s.PlotDerivs("", npts, 0) // 0 => CalcBasisAndDerivs s.PlotDerivs(str4, npts, 1) // 1 => NumericalDeriv plt.SaveD("/tmp/gosl/gm", "bspline03.png") } }
func Test_lognorm03(tst *testing.T) { //verbose() chk.PrintTitle("lognorm03. Rackwitz-Fiessler conversion") dat := &VarData{D: D_Log, M: 10, S: 2} var dist DistLogNormal dist.Init(dat) dat.distr = &dist doplot := false if doplot { plt.SetForEps(1.5, 300) n := 101 x := utl.LinSpace(5, 15, n) y := make([]float64, n) Y := make([]float64, n) for i := 0; i < n; i++ { y[i] = dist.Pdf(x[i]) Y[i] = dist.Cdf(x[i]) } plt.Subplot(2, 1, 1) plt.Plot(x, y, io.Sf("clip_on=0,zorder=10,label=r'$m=%.3f,\\;s=%.3f$'", dist.M, dist.S)) plt.Gll("$x$", "$f(x)$", "leg_out=0, leg_ncol=2") plt.Subplot(2, 1, 2) plt.Plot(x, Y, io.Sf("clip_on=0,zorder=10,label=r'$m=%.3f,\\;s=%.3f$'", dist.M, dist.S)) plt.Gll("$x$", "$F(x)$", "leg_out=0, leg_ncol=2") plt.SaveD("/tmp/gosl", "test_lognorm03.eps") } for i, x := range []float64{10, 20, 50} { // Rackwitz-Fiessler f := dist.Pdf(x) F := dist.Cdf(x) io.Pforan("\nx=%g f(x)=%v F(x)=%v\n", x, f, F) var σNrf, μNrf float64 if F == 0 || F == 1 { // z = Φ⁻¹(F) → -∞ or +∞ chk.Panic("cannot compute equivalent normal parameters @ %g because F=%g", x, F) } else { z := StdInvPhi(F) σNrf = Stdphi(z) / f μNrf = x - σNrf*z if μNrf < 0 { μNrf = 0 σNrf = x / z } } // analytical solution for lognormal distribution μN, σN, invalid := dat.CalcEquiv(x) if invalid { tst.Errorf("CalcEquiv failed\n") return } // check tol := 1e-10 if i > 0 { tol = 1e-6 } err := chk.PrintAnaNum("μN", tol, μN, μNrf, chk.Verbose) if err != nil { tst.Errorf("μN values are different: %v\n", err) //return } err = chk.PrintAnaNum("σN", tol, σN, σNrf, chk.Verbose) if err != nil { tst.Errorf("σN values are different: %v\n", err) //return } } }
func Test_dist_frechet_01(tst *testing.T) { //verbose() chk.PrintTitle("dist_frechet_01") _, dat, err := io.ReadTable("data/frechet.dat") if err != nil { tst.Errorf("cannot read comparison results:\n%v\n", err) return } X, ok := dat["x"] if !ok { tst.Errorf("cannot get x values\n") return } L, ok := dat["l"] // location if !ok { tst.Errorf("cannot get l values\n") return } C, ok := dat["c"] // scale if !ok { tst.Errorf("cannot get c values\n") return } A, ok := dat["a"] // shape if !ok { tst.Errorf("cannot get a values\n") return } YpdfCmp, ok := dat["ypdf"] if !ok { tst.Errorf("cannot get ypdf values\n") return } YcdfCmp, ok := dat["ycdf"] if !ok { tst.Errorf("cannot get ycdf values\n") return } var dist DistFrechet nx := len(X) for i := 0; i < nx; i++ { dist.Init(&VarData{L: L[i], C: C[i], A: A[i]}) Ypdf := dist.Pdf(X[i]) Ycdf := dist.Cdf(X[i]) err := chk.PrintAnaNum("ypdf", 1e-14, YpdfCmp[i], Ypdf, chk.Verbose) if err != nil { tst.Errorf("pdf failed: %v\n", err) return } err = chk.PrintAnaNum("ycdf", 1e-15, YcdfCmp[i], Ycdf, chk.Verbose) if err != nil { tst.Errorf("cdf failed: %v\n", err) return } } }