// msg prints information on residuals func (o *NlSolver) msg(typ string, it int, Ldx, fx_max float64, first, last bool) { if first { io.Pfpink("\n%4s%23s%23s\n", "it", "Ldx", "fx_max") io.Pfpink("%4s%23s%23s\n", "", io.Sf("(%7.1e)", o.fnewt), io.Sf("(%7.1e)", o.ftol)) return } io.Pfyel("%4d%23.15e%23.15e\n", it, Ldx, fx_max) if last { io.Pfgrey(". . . converged with %s. nit=%d, nFeval=%d, nJeval=%d\n", typ, it, o.NFeval, o.NJeval) } }
func Test_GOflt01(tst *testing.T) { //verbose() chk.PrintTitle("GOflt01. float64") Init(1234) xmin := 10.0 xmax := 20.0 vals := make([]float64, NSAMPLES) // using Float64 t0 := time.Now() for i := 0; i < NSAMPLES; i++ { vals[i] = Float64(xmin, xmax) } io.Pforan("time elapsed = %v\n", time.Now().Sub(t0)) hist := Histogram{Stations: []float64{10, 12.5, 15, 17.5, 20}} hist.Count(vals, true) io.Pfpink(TextHist(hist.GenLabels("%4g"), hist.Counts, 60)) // using Float64s t0 = time.Now() Float64s(vals, xmin, xmax) io.Pforan("time elapsed = %v\n", time.Now().Sub(t0)) hist.Count(vals, true) io.Pfblue2(TextHist(hist.GenLabels("%4g"), hist.Counts, 60)) }
func Test_fileio01(tst *testing.T) { //verbose() chk.PrintTitle("fileio01") // start analysis := NewFEM("data/bh16.sim", "", true, false, false, false, chk.Verbose, 0) // domain A domsA := NewDomains(analysis.Sim, analysis.DynCfs, analysis.HydSta, 0, 1, false) if len(domsA) == 0 { tst.Errorf("NewDomains failed\n") return } domA := domsA[0] err := domA.SetStage(0) if err != nil { tst.Errorf("SetStage failed\n%v", err) return } for i, _ := range domA.Sol.Y { domA.Sol.Y[i] = float64(i) } io.Pforan("domA.Sol.Y = %v\n", domA.Sol.Y) // write file tidx := 123 err = domA.SaveSol(tidx, true) if err != nil { tst.Errorf("SaveSol failed:\n%v", err) return } // domain B domsB := NewDomains(analysis.Sim, analysis.DynCfs, analysis.HydSta, 0, 1, false) if len(domsB) == 0 { tst.Errorf("NewDomains failed\n") return } domB := domsB[0] err = domB.SetStage(0) if err != nil { tst.Errorf("SetStage failed\n%v", err) return } io.Pfpink("domB.Sol.Y (before) = %v\n", domB.Sol.Y) // read file err = domB.ReadSol(analysis.Sim.DirOut, analysis.Sim.Key, analysis.Sim.EncType, tidx) if err != nil { tst.Errorf("ReadSol failed:\n%v", err) return } io.Pfgreen("domB.Sol.Y (after) = %v\n", domB.Sol.Y) // check chk.Vector(tst, "Y", 1e-17, domA.Sol.Y, domB.Sol.Y) chk.Vector(tst, "dy/dt", 1e-17, domA.Sol.Dydt, domB.Sol.Dydt) chk.Vector(tst, "d²y/dt²", 1e-17, domA.Sol.D2ydt2, domB.Sol.D2ydt2) }
func Test_ind02(tst *testing.T) { //verbose() chk.PrintTitle("ind02. copy into") rnd.Init(0) nbases := 1 A := get_individual(0, nbases) B := get_individual(1, nbases) fmts := map[string][]string{ "int": {"%2d", "%4d", "%5d"}, // ints "flt": {"%6g", "%6g", "%5g"}, // floats "str": {"%4s", "%2s", "%2s"}, // strings "key": {"%3x", "%3x", "%3x"}, // keys "byt": {"%4s", "%4s", "%4s"}, // bytes "fun": {"%3s", "%3s", "%3s"}, // funcs } io.Pfpink("A = %v\n", A.Output(fmts, false)) io.Pfcyan("B = %v\n", B.Output(fmts, false)) var ops OpsData ops.SetDefault() ops.Pc = 1.0 ops.Cuts = []int{1, 2} ops.Xrange = [][]float64{{0, 1}, {-20, 20}, {-300, 300}} a := A.GetCopy() b := A.GetCopy() IndCrossover(a, b, A, B, 0, &ops) io.Pforan("a = %v\n", a.Output(fmts, false)) io.Pfblue2("b = %v\n", b.Output(fmts, false)) chk.Ints(tst, "a.Ints ", a.Ints, []int{1, -20, 300}) chk.Ints(tst, "b.Ints ", b.Ints, []int{-1, 20, -300}) chk.Strings(tst, "a.Strings", a.Strings, []string{"abc", "Y", "c"}) chk.Strings(tst, "b.Strings", b.Strings, []string{"X", "b", "Z"}) // TODO: add other tests here io.Pf("\n") x := get_individual(0, nbases) x.Ovas = []float64{0, 0} x.Oors = []float64{0, 0, 0} io.Pfblue2("x = %v\n", x.Output(fmts, false)) B.CopyInto(x) chk.Scalar(tst, "ova0", 1e-17, x.Ovas[0], 200) chk.Scalar(tst, "ova1", 1e-17, x.Ovas[1], 100) chk.Scalar(tst, "oor0", 1e-17, x.Oors[0], 15) chk.Scalar(tst, "oor1", 1e-17, x.Oors[1], 25) chk.Scalar(tst, "oor2", 1e-17, x.Oors[2], 35) io.Pforan("x = %v\n", x.Output(fmts, false)) chk.String(tst, x.Output(fmts, false), B.Output(fmts, false)) }
func Test_fileio01(tst *testing.T) { chk.PrintTitle("fileio01") // start if !Start("data/bh16.sim", true, chk.Verbose) { tst.Errorf("test failed\n") } defer End() // domain A distr := false domA := NewDomain(Global.Sim.Regions[0], distr) if domA == nil { tst.Errorf("test failed\n") } if !domA.SetStage(0, Global.Sim.Stages[0], distr) { tst.Errorf("test failed\n") } for i, _ := range domA.Sol.Y { domA.Sol.Y[i] = float64(i) } io.Pforan("domA.Sol.Y = %v\n", domA.Sol.Y) // write file tidx := 123 if !domA.SaveSol(tidx) { tst.Errorf("test failed") return } dir, fnk := Global.Dirout, Global.Fnkey io.Pfblue2("file %v written\n", out_nod_path(dir, fnk, tidx, Global.Rank)) // domain B domB := NewDomain(Global.Sim.Regions[0], distr) if domB == nil { tst.Errorf("test failed\n") } if !domB.SetStage(0, Global.Sim.Stages[0], distr) { tst.Errorf("test failed") } io.Pfpink("domB.Sol.Y (before) = %v\n", domB.Sol.Y) // read file if !domB.ReadSol(dir, fnk, tidx) { tst.Errorf("test failed") return } io.Pfgreen("domB.Sol.Y (after) = %v\n", domB.Sol.Y) // check chk.Vector(tst, "Y", 1e-17, domA.Sol.Y, domB.Sol.Y) chk.Vector(tst, "dy/dt", 1e-17, domA.Sol.Dydt, domB.Sol.Dydt) chk.Vector(tst, "d²y/dt²", 1e-17, domA.Sol.D2ydt2, domB.Sol.D2ydt2) }
func Test_sort05(tst *testing.T) { //verbose() chk.PrintTitle("sort05") a := map[string]int{"a": 1, "z": 2, "c": 3, "y": 4, "d": 5, "b": 6, "x": 7} b := map[string]float64{"a": 1, "z": 2, "c": 3, "y": 4, "d": 5, "b": 6, "x": 7} c := map[string]bool{"a": false, "z": true, "c": false, "y": true, "d": true, "b": false, "x": true} ka := StrIntMapSort(a) kb := StrDblMapSort(b) kc := StrBoolMapSort(c) io.Pforan("sorted_keys(a) = %v\n", ka) io.Pforan("sorted_keys(b) = %v\n", kb) io.Pforan("sorted_keys(c) = %v\n", kc) chk.Strings(tst, "ka", ka, []string{"a", "b", "c", "d", "x", "y", "z"}) chk.Strings(tst, "kb", kb, []string{"a", "b", "c", "d", "x", "y", "z"}) chk.Strings(tst, "kc", kc, []string{"a", "b", "c", "d", "x", "y", "z"}) ka, va := StrIntMapSortSplit(a) io.Pfpink("sorted_keys(a) = %v\n", ka) io.Pfpink("sorted_vals(a) = %v\n", va) chk.Strings(tst, "ka", ka, []string{"a", "b", "c", "d", "x", "y", "z"}) chk.Ints(tst, "va", va, []int{1, 6, 3, 5, 7, 4, 2}) kb, vb := StrDblMapSortSplit(b) io.Pfcyan("sorted_keys(b) = %v\n", kb) io.Pfcyan("sorted_vals(b) = %v\n", vb) chk.Strings(tst, "kb", kb, []string{"a", "b", "c", "d", "x", "y", "z"}) chk.Vector(tst, "vb", 1e-16, vb, []float64{1, 6, 3, 5, 7, 4, 2}) kc, vc := StrBoolMapSortSplit(c) io.Pfcyan("sorted_keys(c) = %v\n", kc) io.Pfcyan("sorted_vals(c) = %v\n", vc) chk.Strings(tst, "kc", kc, []string{"a", "b", "c", "d", "x", "y", "z"}) chk.Bools(tst, "vc", vc, []bool{false, false, false, true, true, true, true}) }
// KrefineN return a new Nurbs with each span divided into ndiv parts = [2, 3, ...] func (o *Nurbs) KrefineN(ndiv int, hughesEtAlPaper bool) *Nurbs { X := make([][]float64, o.gnd) if hughesEtAlPaper { elems := o.Elements() switch o.gnd { case 2: for _, e := range elems { umin, umax := o.b[0].T[e[0]], o.b[0].T[e[1]] vmin, vmax := o.b[1].T[e[2]], o.b[1].T[e[3]] xa := o.Point([]float64{umin, vmin}) xb := o.Point([]float64{umax, vmin}) xc := []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0} io.Pf("xa = %v\n", xa) io.Pf("xb = %v\n", xb) io.Pf("xc = %v\n", xc) xa = o.Point([]float64{umin, vmax}) xb = o.Point([]float64{umax, vmax}) xc = []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0} io.Pfpink("xa, xb, xc = %v, %v, %v\n", xa, xb, xc) chk.Panic("KrefineN with hughesEtAlPaper==true is not implemented in 2D yet") } case 3: chk.Panic("KrefineN with hughesEtAlPaper==true is not implemented in 3D yet") } io.Pfgrey("KrefineN with hughesEtAlPaper==true => not implemented yet\n") return nil } else { for d := 0; d < o.gnd; d++ { nspans := o.b[d].m - 2*o.p[d] - 1 nnewk := nspans * (ndiv - 1) X[d] = make([]float64, nnewk) k := 0 for i := 0; i < nspans; i++ { umin, umax := o.b[d].T[o.p[d]+i], o.b[d].T[o.p[d]+i+1] du := (umax - umin) / float64(ndiv) for j := 1; j < ndiv; j++ { X[d][k] = umin + du*float64(j) k += 1 } } } } return o.Krefine(X) }
func Test_nurbs01(tst *testing.T) { //verbose() chk.PrintTitle("nurbs01") nurbs := get_nurbs_A() faces := nurbs.ExtractSurfaces() spans := nurbs.Elements() ibasis0 := nurbs.IndBasis(spans[0]) ibasis1 := nurbs.IndBasis(spans[1]) io.Pforan("spans = %v\n", spans) chk.Ints(tst, "span0", spans[0], []int{2, 3, 1, 2}) chk.Ints(tst, "span1", spans[1], []int{3, 4, 1, 2}) chk.Ints(tst, "ibasis0", ibasis0, []int{0, 1, 2, 4, 5, 6}) chk.Ints(tst, "ibasis1", ibasis1, []int{1, 2, 3, 5, 6, 7}) shape0 := GetShapeNurbs(nurbs, faces, spans[0]) shape1 := GetShapeNurbs(nurbs, faces, spans[1]) dux := 0.5 duy := 1.0 drx := 2.0 dry := 2.0 r := []float64{0.75, 0.75, 0} shape0.NurbsFunc(shape0.S, shape0.DSdR, r, true, -1) io.Pforan("0: u = %v\n", shape0.U) chk.Scalar(tst, "0: ux", 1e-17, shape0.U[0], (1.0+r[0])*dux/drx) chk.Scalar(tst, "0: uy", 1e-17, shape0.U[1], (1.0+r[1])*duy/dry) chk.Ints(tst, "0: ibasis", shape0.Ibasis, []int{0, 1, 2, 4, 5, 6}) io.Pforan("S(u(r)) = %v\n", shape0.S) shape1.NurbsFunc(shape1.S, shape1.DSdR, r, true, -1) io.Pfpink("\n1: u = %v\n", shape1.U) chk.Scalar(tst, "1: ux", 1e-17, shape1.U[0], 0.5+(1.0+r[0])*dux/drx) chk.Scalar(tst, "1: uy", 1e-17, shape1.U[1], (1.0+r[1])*duy/dry) chk.Ints(tst, "1: ibasis", shape1.Ibasis, []int{1, 2, 3, 5, 6, 7}) if chk.Verbose { gm.PlotNurbs("/tmp/gofem", "tst_nurbs01", nurbs, 21, false, nil) } }
func Test_pareto01(tst *testing.T) { //verbose() chk.PrintTitle("pareto01. compare vectors: Pareto-optimal") u := []float64{1, 2, 3, 4, 5, 6} v := []float64{1, 2, 3, 4, 5, 6} io.Pforan("u = %v\n", u) io.Pfblue2("v = %v\n", v) u_dominates, v_dominates := DblsParetoMin(u, v) io.Pfpink("u_dominates = %v\n", u_dominates) io.Pfpink("v_dominates = %v\n", v_dominates) if u_dominates { tst.Errorf("test failed\n") return } if v_dominates { tst.Errorf("test failed\n") return } v = []float64{1, 1.8, 3, 4, 5, 6} io.Pforan("\nu = %v\n", u) io.Pfblue2("v = %v\n", v) u_dominates, v_dominates = DblsParetoMin(u, v) io.Pfpink("u_dominates = %v\n", u_dominates) io.Pfpink("v_dominates = %v\n", v_dominates) if u_dominates { tst.Errorf("test failed\n") return } if !v_dominates { tst.Errorf("test failed\n") return } v = []float64{1, 2.1, 3, 4, 5, 6} io.Pforan("\nu = %v\n", u) io.Pfblue2("v = %v\n", v) u_dominates, v_dominates = DblsParetoMin(u, v) io.Pfpink("u_dominates = %v\n", u_dominates) io.Pfpink("v_dominates = %v\n", v_dominates) if !u_dominates { tst.Errorf("test failed\n") return } if v_dominates { tst.Errorf("test failed\n") return } }
func RunInvCheck(tst *testing.T, key string, M, CorrectInvM [][]float64, checkI bool, Tol, TolI float64) { m, n := len(M), len(M[0]) Mi := MatAlloc(n, m) t0 := time.Now() err := MatInvG(Mi, M, 1e-13) if err != nil { chk.Panic("%v", err.Error()) } io.Pfpink("Lapack: time elapsed = %v\n", time.Now().Sub(t0)) MMi := MatAlloc(m, m) MMiM := MatAlloc(m, n) MatMul(MMi, 1, M, Mi) // MMi = M * Mi MatMul(MMiM, 1, MMi, M) // MMiM = M * Mi * M == M chk.Matrix(tst, io.Sf("%s => Mi - CorrectInvM ", key), Tol, Mi, CorrectInvM) chk.Matrix(tst, io.Sf("%s => M*Mi*M = M ", key), Tol, MMiM, M) if checkI { I := MatAlloc(m, m) MatSetDiag(I, 1) chk.Matrix(tst, io.Sf("%s => M*Mi = I ", key), TolI, MMi, I) } }
// KrefineN return a new Nurbs with each span divided into ndiv parts = [2, 3, ...] func (o *Nurbs) KrefineN(ndiv int, useCspace bool) *Nurbs { X := make([][]float64, o.gnd) if useCspace { elems := o.Elements() for _, e := range elems { switch o.gnd { case 2: umin, umax := o.b[0].T[e[0]], o.b[0].T[e[1]] vmin, vmax := o.b[1].T[e[2]], o.b[1].T[e[3]] xa := o.Point([]float64{umin, vmin}) xb := o.Point([]float64{umax, vmin}) xc := []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0} io.Pforan("xa, xb, xc = %v, %v, %v\n", xa, xb, xc) xa = o.Point([]float64{umin, vmax}) xb = o.Point([]float64{umax, vmax}) xc = []float64{(xa[0] + xb[0]) / 2.0, (xa[1] + xb[1]) / 2.0} io.Pfpink("xa, xb, xc = %v, %v, %v\n", xa, xb, xc) } } chk.Panic("nurbs.go: KrefineN with useCspace==true => not implemented yet") } else { for d := 0; d < o.gnd; d++ { nspans := o.b[d].m - 2*o.p[d] - 1 nnewk := nspans * (ndiv - 1) X[d] = make([]float64, nnewk) k := 0 for i := 0; i < nspans; i++ { umin, umax := o.b[d].T[o.p[d]+i], o.b[d].T[o.p[d]+i+1] du := (umax - umin) / float64(ndiv) for j := 1; j < ndiv; j++ { X[d][k] = umin + du*float64(j) k += 1 } } } } return o.Krefine(X) }
func Test_map03(tst *testing.T) { //verbose() chk.PrintTitle("map03") m := map[string][]int{ "a": []int{100, 101}, "b": []int{1000}, "c": []int{200, 300, 400}, } io.Pforan("m (before) = %v\n", m) StrIntsMapAppend(&m, "a", 102) io.Pfpink("m (after) = %v\n", m) chk.Ints(tst, "m[\"a\"]", m["a"], []int{100, 101, 102}) chk.Ints(tst, "m[\"b\"]", m["b"], []int{1000}) chk.Ints(tst, "m[\"c\"]", m["c"], []int{200, 300, 400}) StrIntsMapAppend(&m, "d", 666) io.Pfcyan("m (after) = %v\n", m) chk.Ints(tst, "m[\"a\"]", m["a"], []int{100, 101, 102}) chk.Ints(tst, "m[\"b\"]", m["b"], []int{1000}) chk.Ints(tst, "m[\"c\"]", m["c"], []int{200, 300, 400}) chk.Ints(tst, "m[\"d\"]", m["d"], []int{666}) chk.Ints(tst, "m[\"e\"]", m["e"], nil) }
func Test_frechet_03(tst *testing.T) { //verbose() chk.PrintTitle("dist_frechet_03") μ := 10.0 σ := 5.0 δ := σ / μ d := 1.0 + δ*δ io.Pforan("μ=%v σ=%v δ=%v d=%v\n", μ, σ, δ, d) if chk.Verbose { plt.AxHline(d, "color='k'") FrechetPlotCoef("/tmp/gosl", "fig_frechet_coef.eps", 3.0, 5.0) } k := 0.2441618 α := 1.0 / k l := μ - math.Gamma(1.0-k) io.Pfpink("l=%v α=%v\n", l, α) l = 8.782275 α = 4.095645 var dist DistFrechet dist.Init(&VarData{L: l, A: α}) io.Pforan("dist = %+#v\n", dist) io.Pforan("mean = %v\n", dist.Mean()) io.Pforan("var = %v\n", dist.Variance()) io.Pforan("σ = %v\n", math.Sqrt(dist.Variance())) if chk.Verbose { plot_frechet(l, 1, α, 8, 16) plt.SaveD("/tmp/gosl", "rnd_dist_frechet_03.eps") } }
func Test_map01(tst *testing.T) { //verbose() chk.PrintTitle("map01") m := map[int][]int{ 1: []int{100, 101}, 2: []int{1000}, 3: []int{200, 300, 400}, } io.Pforan("m (before) = %v\n", m) IntIntsMapAppend(&m, 1, 102) io.Pfpink("m (after) = %v\n", m) chk.Ints(tst, "m[1]", m[1], []int{100, 101, 102}) chk.Ints(tst, "m[2]", m[2], []int{1000}) chk.Ints(tst, "m[3]", m[3], []int{200, 300, 400}) IntIntsMapAppend(&m, 4, 666) io.Pfcyan("m (after) = %v\n", m) chk.Ints(tst, "m[1]", m[1], []int{100, 101, 102}) chk.Ints(tst, "m[2]", m[2], []int{1000}) chk.Ints(tst, "m[3]", m[3], []int{200, 300, 400}) chk.Ints(tst, "m[4]", m[4], []int{666}) chk.Ints(tst, "m[5]", m[5], nil) }
func Test_ends01(tst *testing.T) { //verbose() chk.PrintTitle("ends01") size := 8 cuts := []int{5, 7} ends := GenerateCxEnds(size, 0, cuts) io.Pfpink("size=%v cuts=%v\n", size, cuts) io.Pfyel("ends = %v\n", ends) chk.IntAssert(len(ends), 3) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") size = 2 cuts = []int{} ends = GenerateCxEnds(size, 0, cuts) io.Pfpink("size=%v cuts=%v\n", size, cuts) io.Pforan("ends = %v\n", ends) chk.Ints(tst, "ends", ends, []int{1, 2}) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") size = 3 ncuts := 3 ends = GenerateCxEnds(size, ncuts, nil) io.Pfpink("size=%v ncuts=%v\n", size, ncuts) io.Pforan("ends = %v\n", ends) chk.Ints(tst, "ends", ends, []int{1, 2, 3}) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") size = 3 ncuts = 2 ends = GenerateCxEnds(size, ncuts, nil) io.Pfpink("size=%v ncuts=%v\n", size, ncuts) io.Pforan("ends = %v\n", ends) chk.Ints(tst, "ends", ends, []int{1, 2, 3}) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") size = 8 cuts = []int{7} ends = GenerateCxEnds(size, 0, cuts) io.Pfpink("size=%v cuts=%v\n", size, cuts) io.Pforan("ends = %v\n", ends) chk.Ints(tst, "ends", ends, []int{7, 8}) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") size = 8 cuts = []int{2, 5} ends = GenerateCxEnds(size, 0, cuts) io.Pfpink("size=%v cuts=%v\n", size, cuts) io.Pforan("ends = %v\n", ends) chk.Ints(tst, "ends", ends, []int{2, 5, 8}) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") size = 20 cuts = []int{1, 5, 15, 17} ends = GenerateCxEnds(size, 0, cuts) io.Pfpink("size=%v cuts=%v\n", size, cuts) io.Pfyel("ends = %v\n", ends) chk.Ints(tst, "ends", ends, []int{1, 5, 15, 17, 20}) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") size = 20 ncuts = 5 ends = GenerateCxEnds(size, ncuts, cuts) io.Pfpink("size=%v cuts=%v\n", size, cuts) io.Pfyel("ends = %v\n", ends) chk.IntAssert(ends[len(ends)-1], size) checkRepeated(ends) io.Pf("\n") }
func Test_isofun01(tst *testing.T) { //verbose() chk.PrintTitle("isofun01. rounded cone") // SMP director parameters // Note: // 1) eps and ϵ have an effect on how close to DP/MC SMP will be // 2) as eps increases, SMP is closer to DP/MC // 3) as ϵ increases, SMP is closer to DP/MC // 4) eps also changes the shape of FC surface a, b, eps, ϵ := -1.0, 0.5, 1e-3, 1e-3 shift := 1.0 // radius r := 2.0 // failure crit parameters and number of stress components φ, ncp := 30.0, 6 // q/p coefficient μ := SmpCalcμ(φ, a, b, eps, ϵ) io.Pforan("μ = %v\n", μ) // isotropic functions var o IsoFun o.Init(a, b, eps, ϵ, shift, ncp, rounded_cone_ffcn, rounded_cone_gfcn, rounded_cone_hfcn) // plot if false { //if true { σcCte := 10.0 M := Phi2M(φ, "oct") rmin, rmax := 0.0, 1.28*M*σcCte nr, nα := 31, 81 //nr, nα := 31, 1001 npolarc := true simplec := true only0 := true grads := false showpts := false ferr := 10.0 PlotOct("fig_isofun01.png", σcCte, rmin, rmax, nr, nα, φ, o.Fa, o.Ga, npolarc, simplec, only0, grads, showpts, true, true, ferr, r, μ) } // 3D view if false { //if true { grads := true gftol := 5e-2 o.View(10, nil, grads, gftol, func(e *vtk.IsoSurf) { e.Nlevels = 7 }, r, μ) } // constants ver := chk.Verbose tol := 1e-6 tol2 := 1e-6 tolq := tol2 // check gradients for idxA := 0; idxA < len(test_nd); idxA++ { //for idxA := 0; idxA < 1; idxA++ { //for idxA := 2; idxA < 3; idxA++ { //for idxA := 10; idxA < 11; idxA++ { //for idxA := 11; idxA < 12; idxA++ { //for idxA := 12; idxA < 13; idxA++ { // tensor AA := test_AA[idxA] A := M_Alloc2(3) Ten2Man(A, AA) io.PfYel("\n\ntst # %d ###################################################################################\n", idxA) io.Pfblue2("A = %v\n", A) // function evaluation and shifted eigenvalues fval, err := o.Fa(A, r, μ) if err != nil { chk.Panic("cannot compute F(A):\n%v", err) } io.Pfpink("shift = %v\n", shift) io.Pforan("p, q = %v, %v\n", o.p, o.q) io.Pforan("f(A) = %v\n", fval) // change tolerances tol3 := tol2 tol2_tmp := tol2 switch idxA { case 7: tolq = 1e-5 case 10: tolq = 2508 // TODO tol3 = 0.772 // TODO: check why test # 10 fails with d2f/dAdA case 11: tol2 = 0.0442 // TODO: check this tol3 = 440 //TODO: check this case 12: tol2 = 1e-3 tol3 = 0.082 // TODO: check this } // check gradients err = o.CheckDerivs(A, tol, tol2, tolq, tol3, ver, r, μ) if err != nil { // plot if true { np := 41 pmin, pmax := -o.p*10, o.p*10 pq_point := []float64{o.p, o.q} o.PlotFfcn("/tmp", io.Sf("t_isofun01_%d.png", idxA), pmin, pmax, np, pq_point, "", "'ro'", nil, nil, r, μ) } // test failed chk.Panic("CheckDerivs failed:%v\n", err) } // recover tolerances tol2 = tol2_tmp } }
func Test_nurbs01(tst *testing.T) { /* 4 (1,2) (2,2) 6 5 2@o--------------o@3 7 | | | | @ -- control point | | o -- node | | (a,b) -- span | | | | 0 0@o--------------o@1 2 1 (1,1) (2,1) 3 */ //verbose() chk.PrintTitle("nurb01. square with initial stress") // fem analysis := NewFEM("data/nurbs01.sim", "", true, false, false, false, chk.Verbose, 0) // set stage err := analysis.SetStage(0) if err != nil { tst.Errorf("SetStage failed:\n%v", err) return } // initialise solution vectors err = analysis.ZeroStage(0, true) if err != nil { tst.Errorf("ZeroStage failed:\n%v", err) return } // domain dom := analysis.Domains[0] // draw NURBS if false { nurbs := dom.Msh.Cells[0].Shp.Nurbs gm.PlotNurbs("/tmp/gofem", "test_nurbs01", nurbs, 21, false, nil) } // nodes and elements chk.IntAssert(len(dom.Nodes), 4) chk.IntAssert(len(dom.Elems), 1) // check dofs for _, nod := range dom.Nodes { chk.IntAssert(len(nod.Dofs), 2) chk.StrAssert(nod.Dofs[0].Key, "ux") chk.StrAssert(nod.Dofs[1].Key, "uy") } // check equations nids, eqs := get_nids_eqs(dom) chk.Ints(tst, "eqs", eqs, utl.IntRange(4*2)) chk.Ints(tst, "nids", nids, []int{0, 1, 2, 3}) // check Umap Umaps := [][]int{ {0, 1, 2, 3, 4, 5, 6, 7}, } for i, ele := range dom.Elems { e := ele.(*ElemU) io.Pfpink("%2d : Umap = %v\n", e.Id(), e.Umap) chk.Ints(tst, "Umap", e.Umap, Umaps[i]) } // constraints chk.IntAssert(len(dom.EssenBcs.Bcs), 4) var ct_ux_eqs []int // equations with ux prescribed [sorted] var ct_uy_eqs []int // equations with uy prescribed [sorted] for _, c := range dom.EssenBcs.Bcs { chk.IntAssert(len(c.Eqs), 1) eq := c.Eqs[0] io.Pfgrey("key=%v eq=%v\n", c.Key, eq) switch c.Key { case "ux": ct_ux_eqs = append(ct_ux_eqs, eq) case "uy": ct_uy_eqs = append(ct_uy_eqs, eq) default: tst.Errorf("key %s is incorrect", c.Key) } } sort.Ints(ct_ux_eqs) sort.Ints(ct_uy_eqs) chk.Ints(tst, "equations with ux prescribed", ct_ux_eqs, []int{0, 4}) chk.Ints(tst, "equations with uy prescribed", ct_uy_eqs, []int{1, 3}) // check displacements tolu := 1e-16 for _, n := range dom.Nodes { eqx := n.GetEq("ux") eqy := n.GetEq("uy") u := []float64{dom.Sol.Y[eqx], dom.Sol.Y[eqy]} chk.Vector(tst, "u", tolu, u, nil) } // analytical solution qnV, qnH := -100.0, -50.0 ν := 0.25 σx, σy := qnH, qnV σz := ν * (σx + σy) σref := []float64{σx, σy, σz, 0} // check stresses e := dom.Elems[0].(*ElemU) tols := 1e-13 for idx, _ := range e.IpsElem { σ := e.States[idx].Sig io.Pforan("σ = %v\n", σ) chk.Vector(tst, "σ", tols, σ, σref) } }
func Test_up01a(tst *testing.T) { /* this tests simulates seepage flow along a column * by reducing the initial hydrostatic pressure at * at the bottom of the column * * using mesh from col104elay.msh * * Nodes / Tags Equations * ux uy pl ux uy pl * 8 o----o----o 9 (-5) 53 54 55 o----o----o 50 51 52 * | 14 | . . . | 58 59 | . . . * | (-1) | . . . | | . . . * 21 o o o 22 (-6) 60 61 . o o o 56 57 . * | 26 | . . . | 62 63 | . . . * | | . . . | | . . . * 6 o----o----o 7 (-4) 39 40 41 o----o----o 36 37 38 * | 13 | . . . | 44 45 | . . . * | (-1) | . . . | | . . . * 19 | o o 20 (-6) 46 47 . | o o 42 43 . * | 25 | . . . | 48 49 | . . . * | | . . . | | . . . * 4 o----o----o 5 (-3) 25 26 27 o----o----o 22 23 24 * | 12 | . . . | 30 31 | . . . * | (-2) | . . . | | . . . * 17 o o o 18 (-6) 32 33 . o o o 28 29 . * | 24 | . . . | 34 35 | . . . * | | . . . | | . . . * 2 o----o----o 3 (-2) 9 10 11 o----o----o 6 7 8 * | 11 | . . . | 16 17 | . . . * | (-2) | . . . | | . . . * 15 o o o 16 (-6) 18 19 o o o 14 15 * | 23 | . . . | 20 21 | . . . * | | . . . | | . . . * 0 o----o----o 1 (-1) 0 1 2 o----o----o 3 4 5 * 10 12 13 */ // capture errors and flush log defer End() //verbose() chk.PrintTitle("up01a") // start simulation if !Start("data/up01.sim", true, chk.Verbose) { chk.Panic("cannot start simulation") } // domain distr := false dom := NewDomain(Global.Sim.Regions[0], distr) if dom == nil { chk.Panic("cannot allocate new domain") } // set stage if !dom.SetStage(0, Global.Sim.Stages[0], distr) { chk.Panic("cannot set stage") } // nodes and elements chk.IntAssert(len(dom.Nodes), 27) chk.IntAssert(len(dom.Elems), 4) if true { // nodes with pl nods_with_pl := map[int]bool{0: true, 2: true, 4: true, 6: true, 8: true, 1: true, 3: true, 5: true, 7: true, 9: true} // check dofs for _, nod := range dom.Nodes { if nods_with_pl[nod.Vert.Id] { chk.IntAssert(len(nod.Dofs), 3) chk.StrAssert(nod.Dofs[0].Key, "ux") chk.StrAssert(nod.Dofs[1].Key, "uy") chk.StrAssert(nod.Dofs[2].Key, "pl") } else { chk.IntAssert(len(nod.Dofs), 2) chk.StrAssert(nod.Dofs[0].Key, "ux") chk.StrAssert(nod.Dofs[1].Key, "uy") } } // check equations nids, eqs := get_nids_eqs(dom) chk.Ints(tst, "eqs", eqs, utl.IntRange(10*3+17*2)) chk.Ints(tst, "nids", nids, []int{ 0, 1, 3, 2, 10, 16, 11, 15, 23, 5, 4, 18, 12, 17, 24, 7, 6, 20, 13, 19, 25, 9, 8, 22, 14, 21, 26, }) // check pmap Pmaps := [][]int{ {2, 5, 8, 11}, {11, 8, 24, 27}, {27, 24, 38, 41}, {41, 38, 52, 55}, } Umaps := [][]int{ {0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, {9, 10, 6, 7, 22, 23, 25, 26, 16, 17, 28, 29, 30, 31, 32, 33, 34, 35}, {25, 26, 22, 23, 36, 37, 39, 40, 30, 31, 42, 43, 44, 45, 46, 47, 48, 49}, {39, 40, 36, 37, 50, 51, 53, 54, 44, 45, 56, 57, 58, 59, 60, 61, 62, 63}, } for i, ele := range dom.Elems { e := ele.(*ElemUP) io.Pfpink("%2d : Pmap = %v\n", e.Id(), e.P.Pmap) io.Pfpink("%2d : Umap = %v\n", e.Id(), e.U.Umap) chk.Ints(tst, "Pmap", e.P.Pmap, Pmaps[i]) chk.Ints(tst, "Umap", e.U.Umap, Umaps[i]) } // constraints chk.IntAssert(len(dom.EssenBcs.Bcs), 9*2+2+3) var ct_ux_eqs []int // equations with ux prescribed [sorted] var ct_uy_eqs []int // equations with uy prescribed [sorted] var ct_pl_eqs []int // equations with pl prescribed [sorted] for _, c := range dom.EssenBcs.Bcs { chk.IntAssert(len(c.Eqs), 1) eq := c.Eqs[0] io.Pfgrey("key=%v eq=%v\n", c.Key, eq) switch c.Key { case "ux": ct_ux_eqs = append(ct_ux_eqs, eq) case "uy": ct_uy_eqs = append(ct_uy_eqs, eq) case "pl": ct_pl_eqs = append(ct_pl_eqs, eq) default: tst.Errorf("key %s is incorrect", c.Key) } } sort.Ints(ct_ux_eqs) sort.Ints(ct_uy_eqs) sort.Ints(ct_pl_eqs) chk.Ints(tst, "equations with ux prescribed", ct_ux_eqs, []int{0, 3, 6, 9, 14, 18, 22, 25, 28, 32, 36, 39, 42, 46, 50, 53, 56, 60}) chk.Ints(tst, "equations with uy prescribed", ct_uy_eqs, []int{1, 4, 13}) chk.Ints(tst, "equations with pl prescribed", ct_pl_eqs, []int{2, 5}) } // initial values @ nodes io.Pforan("initial values @ nodes\n") for _, nod := range dom.Nodes { z := nod.Vert.C[1] for _, dof := range nod.Dofs { u := dom.Sol.Y[dof.Eq] switch dof.Key { case "ux": chk.Scalar(tst, io.Sf("nod %3d : ux(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-17, u, 0) case "uy": chk.Scalar(tst, io.Sf("nod %3d : uy(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-17, u, 0) case "pl": plC, _, _ := Global.HydroSt.Calc(z) chk.Scalar(tst, io.Sf("nod %3d : pl(@ %4g)= %6g", nod.Vert.Id, z, u), 1e-13, u, plC) } } } // intial values @ integration points io.Pforan("initial values @ integration points\n") for _, ele := range dom.Elems { e := ele.(*ElemUP) for idx, ip := range e.P.IpsElem { s := e.P.States[idx] z := e.P.Shp.IpRealCoords(e.P.X, ip)[1] chk.AnaNum(tst, io.Sf("sl(z=%11.8f)", z), 1e-17, s.A_sl, 1, chk.Verbose) } } // parameters ν := 0.2 // Poisson's coefficient K0 := ν / (1.0 - ν) // earth pressure at rest nf := 0.3 // porosity sl := 1.0 // saturation ρL := 1.0 // intrinsic (real) density of liquid ρS_top := 2.0 // intrinsic (real) density of solids in top layer ρS_bot := 3.0 // intrinsic (real) density of solids in bottom layer h := 5.0 // height of each layer g := 10.0 // gravity // densities nl := nf * sl // volume fraction of luqid ns := 1.0 - nf // volume fraction of solid ρl := nl * ρL // partial density of liquid ρs_top := ns * ρS_top // partial density of solids in top layer ρs_bot := ns * ρS_bot // partial density of solids in bottom layer ρ_top := ρl + ρs_top // density of mixture in top layer ρ_bot := ρl + ρs_bot // density of mixture in bottom layer // absolute values of stresses σV_z5 := ρ_top * g * h // total vertical stress @ elevation z = 5 m (absolute value) σV_z0 := σV_z5 + ρ_bot*g*h // total vertical stress @ elevation z = 0 m (absolute value) io.Pfyel("ρ_top = %g\n", ρ_top) io.Pfyel("ρ_bot = %g\n", ρ_bot) io.Pfyel("|ΔσV_top| = %g\n", ρ_top*g*h) io.Pfyel("|ΔσV_bot| = %g\n", ρ_bot*g*h) io.PfYel("|σV|(@ z=0) = %g\n", σV_z0) io.PfYel("|σV|(@ z=5) = %g\n", σV_z5) // stress functions var sig fun.Pts var pres fun.Pts sig.Init(fun.Prms{ &fun.Prm{N: "t0", V: 0.00}, {N: "y0", V: -σV_z0}, &fun.Prm{N: "t1", V: 5.00}, {N: "y1", V: -σV_z5}, &fun.Prm{N: "t2", V: 10.00}, {N: "y2", V: 0.0}, }) pres.Init(fun.Prms{ &fun.Prm{N: "t0", V: 0.00}, {N: "y0", V: 100}, &fun.Prm{N: "t1", V: 10.00}, {N: "y1", V: 0}, }) // check stresses io.Pforan("initial stresses @ integration points\n") for _, ele := range dom.Elems { e := ele.(*ElemUP) for idx, ip := range e.U.IpsElem { z := e.U.Shp.IpRealCoords(e.U.X, ip)[1] σe := e.U.States[idx].Sig sv := sig.F(z, nil) sve := sv + pres.F(z, nil) she := sve * K0 if math.Abs(σe[2]-σe[0]) > 1e-17 { tst.Errorf("[1;31mσx is not equal to σz: %g != %g[0m\n", σe[2], σe[0]) return } if math.Abs(σe[3]) > 1e-17 { tst.Errorf("[1;31mσxy is not equal to zero: %g != 0[0m\n", σe[3]) return } chk.AnaNum(tst, io.Sf("sx(z=%11.8f)", z), 0.0003792, σe[0], she, chk.Verbose) chk.AnaNum(tst, io.Sf("sy(z=%11.8f)", z), 0.001517, σe[1], sve, chk.Verbose) } } return }
func Test_mylab06(tst *testing.T) { //verbose() chk.PrintTitle("mylab06. scaling") // |dx|>0: increasing io.Pfblue2("\n|dx|>0: increasing\n") reverse := false useinds := true x := []float64{10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} s := make([]float64, len(x)) Scaling(s, x, -2.0, 1e-16, reverse, useinds) io.Pfpink("x = %v\n", x) io.Pforan("s = %v\n", s) chk.Vector(tst, "s", 1e-15, s, LinSpace(-2, -1, len(x))) // |dx|>0: reverse io.Pfblue2("\n|dx|>0: reverse\n") reverse = true Scaling(s, x, -3.0, 1e-16, reverse, useinds) io.Pfpink("x = %v\n", x) io.Pforan("s = %v\n", s) chk.Vector(tst, "s", 1e-15, s, LinSpace(-2, -3, len(x))) // |dx|>0: increasing io.Pfblue2("\n|dx|>0: increasing (shuffled)\n") reverse = false x = []float64{11, 10, 12, 19, 15, 20, 17, 16, 18, 13, 14} Scaling(s, x, 0.0, 1e-16, reverse, useinds) io.Pfpink("x = %v\n", x) io.Pforan("s = %v\n", s) chk.Vector(tst, "s", 1e-15, s, []float64{0.1, 0.0, 0.2, 0.9, 0.5, 1.0, 0.7, 0.6, 0.8, 0.3, 0.4}) // |dx|=0: increasing (using indices) io.Pfblue2("\n|dx|=0: increasing (using indices)\n") reverse = false x = []float64{123, 123, 123, 123, 123} s = make([]float64, len(x)) Scaling(s, x, 10.0, 1e-16, reverse, useinds) io.Pfpink("x = %v\n", x) io.Pforan("s = %v\n", s) chk.Vector(tst, "s", 1e-15, s, []float64{10, 10.25, 10.5, 10.75, 11}) // |dx|=0: reverse (using indices) io.Pfblue2("\n|dx|=0: reverse (using indices)\n") reverse = true Scaling(s, x, 10.0, 1e-16, reverse, useinds) io.Pfpink("x = %v\n", x) io.Pforan("s = %v\n", s) chk.Vector(tst, "s", 1e-15, s, []float64{11, 10.75, 10.5, 10.25, 10}) // |dx|=0: increasing (not using indices) io.Pfblue2("\n|dx|=0: increasing (not using indices)\n") reverse = false useinds = false Scaling(s, x, 88.0, 1e-16, reverse, useinds) io.Pfpink("x = %v\n", x) io.Pforan("s = %v\n", s) chk.Vector(tst, "s", 1e-15, s, DblVals(len(x), 88)) // |dx|=0: reverse (not using indices) io.Pfblue2("\n|dx|=0: reverse (not using indices)\n") reverse = true Scaling(s, x, 88.0, 1e-16, reverse, useinds) io.Pfpink("x = %v\n", x) io.Pforan("s = %v\n", s) chk.Vector(tst, "s", 1e-15, s, DblVals(len(x), 88)) }
func Test_smpinvs02(tst *testing.T) { //verbose() chk.PrintTitle("smpinvs02") // coefficients for smp invariants smp_a := -1.0 smp_b := 0.5 smp_β := 1e-1 // derivative values become too high with smp_ϵ := 1e-1 // small β and ϵ @ zero // constants for checking derivatives dver := chk.Verbose dtol := 1e-9 dtol2 := 1e-8 // run tests nd := test_nd for idxA := 0; idxA < len(test_nd); idxA++ { //for idxA := 0; idxA < 1; idxA++ { //for idxA := 10; idxA < 11; idxA++ { // tensor and eigenvalues A := test_AA[idxA] a := M_Alloc2(nd[idxA]) Ten2Man(a, A) L := make([]float64, 3) M_EigenValsNum(L, a) // SMP director N := make([]float64, 3) n := make([]float64, 3) m := SmpDirector(N, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n, m, N) // output io.PfYel("\n\ntst # %d ###################################################################################\n", idxA) io.Pforan("L = %v\n", L) io.Pforan("N = %v\n", N) io.Pforan("m = %v\n", m) io.Pfpink("n = %v\n", n) chk.Vector(tst, "L", 1e-12, L, test_λ[idxA]) chk.Scalar(tst, "norm(n)==1", 1e-15, la.VecNorm(n), 1) chk.Scalar(tst, "m=norm(N)", 1e-14, m, la.VecNorm(N)) // dN/dL var tmp float64 N_tmp := make([]float64, 3) dNdL := make([]float64, 3) SmpDirectorDeriv1(dNdL, L, smp_a, smp_b, smp_β, smp_ϵ) io.Pfpink("\ndNdL = %v\n", dNdL) for i := 0; i < 3; i++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[i] = L[i], x SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) L[i] = tmp return N_tmp[i] }, L[i], 1e-6) chk.AnaNum(tst, io.Sf("dN/dL[%d][%d]", i, i), dtol, dNdL[i], dnum, dver) } // dm/dL n_tmp := make([]float64, 3) dmdL := make([]float64, 3) SmpNormDirectorDeriv1(dmdL, m, N, dNdL) io.Pfpink("\ndmdL = %v\n", dmdL) for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) L[j] = tmp return m_tmp }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("dm/dL[%d]", j), dtol, dmdL[j], dnum, dver) } // dn/dL dndL := la.MatAlloc(3, 3) SmpUnitDirectorDeriv1(dndL, m, N, dNdL, dmdL) io.Pfpink("\ndndL = %v\n", dndL) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n_tmp, m_tmp, N_tmp) L[j] = tmp return n_tmp[i] }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("dn/dL[%d][%d]", i, j), dtol, dndL[i][j], dnum, dver) } } // change tolerance dtol2_tmp := dtol2 if idxA == 10 || idxA == 11 { dtol2 = 1e-6 } // d²m/dLdL dNdL_tmp := make([]float64, 3) dmdL_tmp := make([]float64, 3) d2NdL2 := make([]float64, 3) d2mdLdL := la.MatAlloc(3, 3) SmpDirectorDeriv2(d2NdL2, L, smp_a, smp_b, smp_β, smp_ϵ) SmpNormDirectorDeriv2(d2mdLdL, L, smp_a, smp_b, smp_β, smp_ϵ, m, N, dNdL, d2NdL2, dmdL) io.Pfpink("\nd2mdLdL = %v\n", d2mdLdL) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpDirectorDeriv1(dNdL_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpNormDirectorDeriv1(dmdL_tmp, m_tmp, N_tmp, dNdL_tmp) L[j] = tmp return dmdL_tmp[i] }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("d2m/dL[%d]dL[%d]", i, j), dtol2, d2mdLdL[i][j], dnum, dver) } } // d²N/dLdL io.Pfpink("\nd²N/dLdL\n") for i := 0; i < 3; i++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[i] = L[i], x SmpDirectorDeriv1(dNdL_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) L[i] = tmp return dNdL_tmp[i] }, L[i], 1e-6) chk.AnaNum(tst, io.Sf("d²N[%d]/dL[%d]dL[%d]", i, i, i), dtol2, d2NdL2[i], dnum, dver) } // d²n/dLdL io.Pfpink("\nd²n/dLdL\n") dndL_tmp := la.MatAlloc(3, 3) d2ndLdL := utl.Deep3alloc(3, 3, 3) SmpUnitDirectorDeriv2(d2ndLdL, m, N, dNdL, d2NdL2, dmdL, n, d2mdLdL, dndL) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { for k := 0; k < 3; k++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[k] = L[k], x m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpDirectorDeriv1(dNdL_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpNormDirectorDeriv1(dmdL_tmp, m_tmp, N_tmp, dNdL_tmp) SmpUnitDirectorDeriv1(dndL_tmp, m_tmp, N_tmp, dNdL_tmp, dmdL_tmp) L[k] = tmp return dndL_tmp[i][j] }, L[k], 1e-6) chk.AnaNum(tst, io.Sf("d²n[%d]/dL[%d]dL[%d]", i, j, k), dtol2, d2ndLdL[i][j][k], dnum, dver) } } } // recover tolerance dtol2 = dtol2_tmp // SMP derivs //if false { if true { io.Pfpink("\nSMP derivs\n") dndL_ := la.MatAlloc(3, 3) dNdL_ := make([]float64, 3) d2ndLdL_ := utl.Deep3alloc(3, 3, 3) N_ := make([]float64, 3) F_ := make([]float64, 3) G_ := make([]float64, 3) m_ := SmpDerivs1(dndL_, dNdL_, N_, F_, G_, L, smp_a, smp_b, smp_β, smp_ϵ) SmpDerivs2(d2ndLdL_, L, smp_a, smp_b, smp_β, smp_ϵ, m_, N_, F_, G_, dNdL_, dndL_) chk.Scalar(tst, "m_", 1e-14, m_, m) chk.Vector(tst, "N_", 1e-15, N_, N) chk.Vector(tst, "dNdL_", 1e-15, dNdL_, dNdL) chk.Matrix(tst, "dndL_", 1e-13, dndL_, dndL) chk.Deep3(tst, "d2ndLdL_", 1e-11, d2ndLdL_, d2ndLdL) } } }
func Test_list02(tst *testing.T) { //verbose() chk.PrintTitle("list02. DblSlist.Append") var L DblSlist L.Append(true, 0.0) io.Pforan("L.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "0: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "0: vals", 1e-17, L.Vals, []float64{0.0}) chk.Ints(tst, "0: ptrs", L.Ptrs, []int{0, 1}) L.Append(true, 1.0) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "1: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "1: vals", 1e-17, L.Vals, []float64{0.0, 1.0}) chk.Ints(tst, "1: ptrs", L.Ptrs, []int{0, 1, 2}) L.Append(false, 1.1) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "2: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "2: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1}) chk.Ints(tst, "2: ptrs", L.Ptrs, []int{0, 1, 3}) L.Append(false, 1.2) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "3: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "3: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2}) chk.Ints(tst, "3: ptrs", L.Ptrs, []int{0, 1, 4}) L.Append(false, 1.3) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "4: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "4: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3}) chk.Ints(tst, "4: ptrs", L.Ptrs, []int{0, 1, 5}) L.Append(true, 2.0) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "5: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "5: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0}) chk.Ints(tst, "5: ptrs", L.Ptrs, []int{0, 1, 5, 6}) L.Append(false, 2.1) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "6: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "6: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1}) chk.Ints(tst, "6: ptrs", L.Ptrs, []int{0, 1, 5, 7}) L.Append(true, 3.0) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "7: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "7: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0}) chk.Ints(tst, "7: ptrs", L.Ptrs, []int{0, 1, 5, 7, 8}) L.Append(false, 3.1) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "8: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "8: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0, 3.1}) chk.Ints(tst, "8: ptrs", L.Ptrs, []int{0, 1, 5, 7, 9}) L.Append(false, 3.2) io.Pforan("\nL.Vals = %v\n", L.Vals) io.Pfpink("L.Ptrs = %v\n", L.Ptrs) chk.Ints(tst, "9: lens", []int{L.Ptrs[len(L.Ptrs)-1]}, []int{len(L.Vals)}) chk.Vector(tst, "9: vals", 1e-17, L.Vals, []float64{0.0, 1.0, 1.1, 1.2, 1.3, 2.0, 2.1, 3.0, 3.1, 3.2}) chk.Ints(tst, "9: ptrs", L.Ptrs, []int{0, 1, 5, 7, 10}) io.Pf("\n") L.Print("%10g") }
// Solve solves y(x) = 0 for x in [xa, xb] with f(xa) * f(xb) < 0 // // Based on ZEROIN C math library: http://www.netlib.org/c/ // By: Oleg Keselyov <[email protected], [email protected]> May 23, 1991 // // G.Forsythe, M.Malcolm, C.Moler, Computer methods for mathematical // computations. M., Mir, 1980, p.180 of the Russian edition // // The function makes use of the bissection procedure combined with // the linear or quadric inverse interpolation. // At every step program operates on three abscissae - a, b, and c. // b - the last and the best approximation to the root // a - the last but one approximation // c - the last but one or even earlier approximation than a that // 1) |f(b)| <= |f(c)| // 2) f(b) and f(c) have opposite signs, i.e. b and c confine // the root // At every step Zeroin selects one of the two new approximations, the // former being obtained by the bissection procedure and the latter // resulting in the interpolation (if a,b, and c are all different // the quadric interpolation is utilized, otherwise the linear one). // If the latter (i.e. obtained by the interpolation) point is // reasonable (i.e. lies within the current interval [b,c] not being // too close to the boundaries) it is accepted. The bissection result // is used in the other case. Therefore, the range of uncertainty is // ensured to be reduced at least by the factor 1.6 // func (o *Brent) Solve(xa, xb float64, silent bool) (res float64, err error) { // basic variables and function evaluation a := xa // the last but one approximation b := xb // the last and the best approximation to the root c := a // the last but one or even earlier approximation than a that fa, erra := o.Ffcn(a) fb, errb := o.Ffcn(b) o.NFeval = 2 if erra != nil { return 0, chk.Err(_brent_err1, "a", xa, erra.Error()) } if errb != nil { return 0, chk.Err(_brent_err1, "b", xb, errb.Error()) } fc := fa // check input if fa*fb >= -EPS { return 0, chk.Err(_brent_err2, xa, xb, fa, fb) } // message if !silent { io.Pfpink("%4s%23s%23s%23s\n", "it", "x", "f(x)", "err") io.Pfpink("%50s%23.1e\n", "", o.Tol) } // solve var prev_step float64 // distance from the last but one to the last approximation var tol_act float64 // actual tolerance var p, q float64 // interpol. step is calculated in the form p/q (divisions are delayed) var new_step float64 // step at this iteration var t1, cb, t2 float64 // auxiliary variables for o.It = 0; o.It < o.MaxIt; o.It++ { // distance prev_step = b - a // swap data for b to be the best approximation if math.Abs(fc) < math.Abs(fb) { a = b b = c c = a fa = fb fb = fc fc = fa } tol_act = 2.0*EPS*math.Abs(b) + o.Tol/2.0 new_step = (c - b) / 2.0 // converged? if !silent { io.Pfyel("%4d%23.15e%23.15e%23.15e\n", o.It, b, fb, math.Abs(new_step)) } if math.Abs(new_step) <= tol_act || fb == 0.0 { return b, nil } // decide if the interpolation can be tried if math.Abs(prev_step) >= tol_act && math.Abs(fa) > math.Abs(fb) { // if prev_step was large enough and was in true direction, interpolatiom may be tried cb = c - b // with two distinct points, linear interpolation must be applied if a == c { t1 = fb / fa p = cb * t1 q = 1.0 - t1 // otherwise, quadric inverse interpolation is applied } else { q = fa / fc t1 = fb / fc t2 = fb / fa p = t2 * (cb*q*(q-t1) - (b-a)*(t1-1.0)) q = (q - 1.0) * (t1 - 1.0) * (t2 - 1.0) } // p was calculated with the opposite sign; // make p positive and assign possible minus to q if p > 0.0 { q = -q } else { p = -p } // if b+p/q falls in [b,c] and isn't too large, it is accepted // if p/q is too large then the bissection procedure can reduce [b,c] range to more extent if p < (0.75*cb*q-math.Abs(tol_act*q)/2.0) && p < math.Abs(prev_step*q/2.0) { new_step = p / q } } // adjust the step to be not less than tolerance if math.Abs(new_step) < tol_act { if new_step > 0.0 { new_step = tol_act } else { new_step = -tol_act } } // save the previous approximation a = b fa = fb // do step to a new approximation b += new_step fb, errb = o.Ffcn(b) o.NFeval += 1 if errb != nil { return 0, chk.Err(_brent_err1, "", b, errb.Error()) } // adjust c for it to have a sign opposite to that of b if (fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0) { c = a fc = fa } } // did not converge return fb, chk.Err(_brent_err3, "Solve", o.It) }
func Test_geninvs01(tst *testing.T) { //verbose() chk.PrintTitle("geninvs01") // coefficients for smp invariants smp_a := -1.0 smp_b := 0.5 smp_β := 1e-1 // derivative values become too high with smp_ϵ := 1e-1 // small β and ϵ @ zero // constants for checking derivatives dver := chk.Verbose dtol := 1e-6 dtol2 := 1e-6 // run tests nd := test_nd for idxA := 0; idxA < len(test_nd); idxA++ { //for idxA := 10; idxA < 11; idxA++ { // tensor and eigenvalues A := test_AA[idxA] a := M_Alloc2(nd[idxA]) Ten2Man(a, A) L := make([]float64, 3) M_EigenValsNum(L, a) // SMP derivs and SMP director dndL := la.MatAlloc(3, 3) dNdL := make([]float64, 3) d2ndLdL := utl.Deep3alloc(3, 3, 3) N := make([]float64, 3) F := make([]float64, 3) G := make([]float64, 3) m := SmpDerivs1(dndL, dNdL, N, F, G, L, smp_a, smp_b, smp_β, smp_ϵ) SmpDerivs2(d2ndLdL, L, smp_a, smp_b, smp_β, smp_ϵ, m, N, F, G, dNdL, dndL) n := make([]float64, 3) SmpUnitDirector(n, m, N) // SMP invariants p, q, err := GenInvs(L, n, smp_a) if err != nil { chk.Panic("SmpInvs failed:\n%v", err) } // output io.PfYel("\n\ntst # %d ###################################################################################\n", idxA) io.Pfblue2("L = %v\n", L) io.Pforan("n = %v\n", n) io.Pforan("p = %v\n", p) io.Pforan("q = %v\n", q) // check invariants tvec := make([]float64, 3) GenTvec(tvec, L, n) proj := make([]float64, 3) // projection of tvec along n tdn := la.VecDot(tvec, n) // tvec dot n for i := 0; i < 3; i++ { proj[i] = tdn * n[i] } norm_proj := la.VecNorm(proj) norm_tvec := la.VecNorm(tvec) q_ := GENINVSQEPS + math.Sqrt(norm_tvec*norm_tvec-norm_proj*norm_proj) io.Pforan("proj = %v\n", proj) io.Pforan("norm(proj) = %v == p\n", norm_proj) chk.Scalar(tst, "p", 1e-14, math.Abs(p), norm_proj) chk.Scalar(tst, "q", 1e-13, q, q_) // dt/dL var tmp float64 N_tmp := make([]float64, 3) n_tmp := make([]float64, 3) tvec_tmp := make([]float64, 3) dtdL := la.MatAlloc(3, 3) GenTvecDeriv1(dtdL, L, n, dndL) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n_tmp, m_tmp, N_tmp) GenTvec(tvec_tmp, L, n_tmp) L[j] = tmp return tvec_tmp[i] }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("dt/dL[%d][%d]", i, j), dtol, dtdL[i][j], dnum, dver) } } // d²t/dLdL io.Pfpink("\nd²t/dLdL\n") dNdL_tmp := make([]float64, 3) dndL_tmp := la.MatAlloc(3, 3) dtdL_tmp := la.MatAlloc(3, 3) for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { for k := 0; k < 3; k++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[k] = L[k], x m_tmp := SmpDerivs1(dndL_tmp, dNdL_tmp, N_tmp, F, G, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n_tmp, m_tmp, N_tmp) GenTvecDeriv1(dtdL_tmp, L, n_tmp, dndL_tmp) L[k] = tmp return dtdL_tmp[i][j] }, L[k], 1e-6) dana := GenTvecDeriv2(i, j, k, L, dndL, d2ndLdL[i][j][k]) chk.AnaNum(tst, io.Sf("d²t[%d]/dL[%d]dL[%d]", i, j, k), dtol2, dana, dnum, dver) } } } // change tolerance dtol_tmp := dtol switch idxA { case 5, 11: dtol = 1e-5 case 12: dtol = 0.0013 } // first order derivatives dpdL := make([]float64, 3) dqdL := make([]float64, 3) p_, q_, err := GenInvsDeriv1(dpdL, dqdL, L, n, dndL, smp_a) if err != nil { chk.Panic("%v", err) } chk.Scalar(tst, "p", 1e-17, p, p_) chk.Scalar(tst, "q", 1e-17, q, q_) var ptmp, qtmp float64 io.Pfpink("\ndp/dL\n") for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n_tmp, m_tmp, N_tmp) ptmp, _, err = GenInvs(L, n_tmp, smp_a) if err != nil { chk.Panic("DerivCentral: SmpInvs failed:\n%v", err) } L[j] = tmp return ptmp }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("dp/dL[%d]", j), dtol, dpdL[j], dnum, dver) } io.Pfpink("\ndq/dL\n") for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDirector(N_tmp, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n_tmp, m_tmp, N_tmp) _, qtmp, err = GenInvs(L, n_tmp, smp_a) if err != nil { chk.Panic("DerivCentral: SmpInvs failed:\n%v", err) } L[j] = tmp return qtmp }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("dq/dL[%d]", j), dtol, dqdL[j], dnum, dver) } // recover tolerance dtol = dtol_tmp // change tolerance io.Pforan("dtol2 = %v\n", dtol2) dtol2_tmp := dtol2 switch idxA { case 5: dtol2 = 1e-5 case 10: dtol2 = 0.72 case 11: dtol2 = 1e-5 case 12: dtol2 = 544 } // second order derivatives dpdL_tmp := make([]float64, 3) dqdL_tmp := make([]float64, 3) d2pdLdL := la.MatAlloc(3, 3) d2qdLdL := la.MatAlloc(3, 3) GenInvsDeriv2(d2pdLdL, d2qdLdL, L, n, dpdL, dqdL, p, q, dndL, d2ndLdL, smp_a) io.Pfpink("\nd²p/dLdL\n") for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDerivs1(dndL_tmp, dNdL_tmp, N_tmp, F, G, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n_tmp, m_tmp, N_tmp) GenInvsDeriv1(dpdL_tmp, dqdL_tmp, L, n_tmp, dndL_tmp, smp_a) L[j] = tmp return dpdL_tmp[i] }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("d²p/dL[%d][%d]", i, j), dtol2, d2pdLdL[i][j], dnum, dver) } } io.Pfpink("\nd²q/dLdL\n") for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { dnum, _ := num.DerivCentral(func(x float64, args ...interface{}) (res float64) { tmp, L[j] = L[j], x m_tmp := SmpDerivs1(dndL_tmp, dNdL_tmp, N_tmp, F, G, L, smp_a, smp_b, smp_β, smp_ϵ) SmpUnitDirector(n_tmp, m_tmp, N_tmp) GenInvsDeriv1(dpdL_tmp, dqdL_tmp, L, n_tmp, dndL_tmp, smp_a) L[j] = tmp return dqdL_tmp[i] }, L[j], 1e-6) chk.AnaNum(tst, io.Sf("d²q/dL[%d][%d]", i, j), dtol2, d2qdLdL[i][j], dnum, dver) } } // recover tolerance dtol2 = dtol2_tmp } }
// 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 }
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") } }