Пример #1
0
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
		}
	}
}
Пример #2
0
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
		}
	}
}
Пример #3
0
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
		}
	}
}
Пример #4
0
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
		}
	}
}
Пример #5
0
// 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
}
Пример #6
0
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")
}
Пример #7
0
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()
}
Пример #8
0
// 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
}
Пример #9
0
// 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
}
Пример #10
0
// 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
}
Пример #11
0
// 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
}
Пример #12
0
// 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
}
Пример #13
0
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")
	}
}
Пример #14
0
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
		}
	}
}
Пример #15
0
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
		}
	}
}