// PlotTwoVarsContour plots contour for two variables problem. len(x) == 2 // Input // dirout -- directory to save files // fnkey -- file name key for eps figure // x -- solution. can be <nil> // np -- number of points for contour // extra -- called just before saving figure // axequal -- axis.equal // vmin -- min 0 values // vmax -- max 1 values // f -- function to plot filled contour. can be <nil> // gs -- functions to plot contour @ level 0. can be <nil> func PlotTwoVarsContour(dirout, fnkey string, x []float64, np int, extra func(), axequal bool, vmin, vmax []float64, f TwoVarsFunc_t, gs ...TwoVarsFunc_t) { if fnkey == "" { return } chk.IntAssert(len(vmin), 2) chk.IntAssert(len(vmax), 2) V0, V1 := utl.MeshGrid2D(vmin[0], vmax[0], vmin[1], vmax[1], np, np) var Zf [][]float64 var Zg [][][]float64 if f != nil { Zf = la.MatAlloc(np, np) } if len(gs) > 0 { Zg = utl.Deep3alloc(len(gs), np, np) } xtmp := make([]float64, 2) for i := 0; i < np; i++ { for j := 0; j < np; j++ { xtmp[0], xtmp[1] = V0[i][j], V1[i][j] if f != nil { Zf[i][j] = f(xtmp) } for k, g := range gs { Zg[k][i][j] = g(xtmp) } } } plt.Reset() plt.SetForEps(0.8, 350) if f != nil { cmapidx := 0 plt.Contour(V0, V1, Zf, io.Sf("fsz=7, cmapidx=%d", cmapidx)) } for k, _ := range gs { plt.ContourSimple(V0, V1, Zg[k], false, 8, "zorder=5, levels=[0], colors=['yellow'], linewidths=[2], clip_on=0") } if x != nil { plt.PlotOne(x[0], x[1], "'r*', label='optimum', zorder=10") } if extra != nil { extra() } if dirout == "" { dirout = "." } plt.Cross("clr='grey'") plt.SetXnticks(11) plt.SetYnticks(11) if axequal { plt.Equal() } plt.AxisRange(vmin[0], vmax[0], vmin[1], vmax[1]) args := "leg_out='1', leg_ncol=4, leg_hlen=1.5" plt.Gll("$x_0$", "$x_1$", args) plt.SaveD(dirout, fnkey+".eps") }
// Init initialises Nurbs func (o *Nurbs) Init(gnd int, ords []int, knots [][]float64) { // essential o.gnd = gnd o.p = make([]int, 3) // B-splines o.b = make([]Bspline, o.gnd) o.n = make([]int, 3) for d := 0; d < o.gnd; d++ { o.p[d] = ords[d] o.b[d].Init(knots[d], o.p[d]) o.n[d] = o.b[d].NumBasis() if o.n[d] < 2 { chk.Panic("number of knots is incorrect for dimension %d. n == %d is invalid", d, o.n[d]) } } for d := o.gnd; d < 3; d++ { o.n[d] = 1 } // ids of control points nctrl := o.n[0] * o.n[1] * o.n[2] o.l2i = make([][]int, nctrl) for l := 0; l < nctrl; l++ { o.l2i[l] = make([]int, 3) switch o.gnd { case 1: o.l2i[l][0] = l case 2: o.l2i[l][0] = l % o.n[0] // i o.l2i[l][1] = l / o.n[0] // j case 3: c := l % (o.n[0] * o.n[1]) o.l2i[l][0] = c % o.n[0] // i o.l2i[l][1] = c / o.n[0] // j o.l2i[l][2] = l / (o.n[0] * o.n[1]) // k } } // auxiliary o.span = make([]int, 3) o.idx = make([]int, 3) o.cw = make([]float64, 4) o.rr = utl.Deep3alloc(o.p[0]+1, o.p[1]+1, o.p[2]+1) o.drr = utl.Deep4alloc(o.p[0]+1, o.p[1]+1, o.p[2]+1, o.gnd) o.dww = make([]float64, o.gnd) }
// 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 }
// Init initialises this structure func (o *PrincStrainsUp) Init(ndim int, prms fun.Prms, mdl EPmodel) (err error) { // constants o.Fzero = 1e-9 o.Nsig = 2 * ndim // tolerances atol, rtol, ftol := 1e-8, 1e-8, 1e-9 // flags o.Nbsmp = 5 o.Fcoef = 1.0 o.ChkJacTol = 1e-4 // read parameters for _, p := range prms { switch p.N { // tolerances case "atol": atol = p.V case "rtol": rtol = p.V case "ftol": ftol = p.V // flags case "nbsmp": o.Nbsmp = int(p.V) case "fcoef": o.Fcoef = p.V case "lineS": o.LineS = p.V case "chkJac": o.ChkJac = p.V > 0 case "chkSilent": o.ChkSilent = p.V > 0 // debugging case "dbgShowR": o.DbgShowR = p.V > 0 case "dbgOn": o.DbgOn = p.V > 0 case "dbgPlot": o.DbgPlot = p.V > 0 case "dbgEid": o.DbgEid = int(p.V) case "dbgIpid": o.DbgIpId = int(p.V) case "dbgTime": o.DbgTime = p.V } } // model o.Mdl = mdl o.Nalp, o.Nsurf = o.Mdl.Info() // variables o.Lσ = make([]float64, 3) o.Lεe = make([]float64, 3) o.Lεetr = make([]float64, 3) o.P = la.MatAlloc(3, o.Nsig) o.αn = make([]float64, o.Nalp) o.h = make([]float64, 3) o.A = make([]float64, o.Nalp) o.N = make([]float64, 3) o.Ne = make([]float64, 3) o.Nb = make([]float64, 3) o.Mb = la.MatAlloc(3, 3) o.Mbe = la.MatAlloc(3, 3) o.De = la.MatAlloc(3, 3) o.Dt = la.MatAlloc(3, 3) o.a = la.MatAlloc(o.Nalp, 3) o.b = la.MatAlloc(o.Nalp, 3) o.be = la.MatAlloc(o.Nalp, 3) o.c = la.MatAlloc(o.Nalp, o.Nalp) o.x = make([]float64, 4+o.Nalp) o.J = la.MatAlloc(4+o.Nalp, 4+o.Nalp) o.Ji = la.MatAlloc(4+o.Nalp, 4+o.Nalp) o.dPdT = utl.Deep3alloc(3, o.Nsig, o.Nsig) // nonlinear solver useDn, numJ := true, false o.nls.Init(4+o.Nalp, o.ffcn, nil, o.JfcnD, useDn, numJ, map[string]float64{ "lSearch": o.LineS, "atol": atol, "rtol": rtol, "ftol": ftol, }) o.nls.ChkConv = false return }
// Plot plots contour func (o *SimpleFltProb) Plot(fnkey string) { // check if !o.C.DoPlot { return } // limits and meshgrid xmin, xmax := o.C.RangeFlt[0][0], o.C.RangeFlt[0][1] ymin, ymax := o.C.RangeFlt[1][0], o.C.RangeFlt[1][1] // auxiliary variables X, Y := utl.MeshGrid2D(xmin, xmax, ymin, ymax, o.PltNpts, o.PltNpts) Zf := utl.DblsAlloc(o.PltNpts, o.PltNpts) var Zg [][][]float64 var Zh [][][]float64 if o.ng > 0 { Zg = utl.Deep3alloc(o.ng, o.PltNpts, o.PltNpts) } if o.nh > 0 { Zh = utl.Deep3alloc(o.nh, o.PltNpts, o.PltNpts) } // compute values x := make([]float64, 2) for i := 0; i < o.PltNpts; i++ { for j := 0; j < o.PltNpts; j++ { x[0], x[1] = X[i][j], Y[i][j] o.Fcn(o.ff[0], o.gg[0], o.hh[0], x) Zf[i][j] = o.ff[0][o.PltIdxF] for k, g := range o.gg[0] { Zg[k][i][j] = g } for k, h := range o.hh[0] { Zh[k][i][j] = h } } } // prepare plot area plt.Reset() plt.SetForEps(0.8, 350) // plot f if o.PltArgs != "" { o.PltArgs = "," + o.PltArgs } if o.PltCsimple { plt.ContourSimple(X, Y, Zf, true, 7, "colors=['k'], fsz=7"+o.PltArgs) } else { plt.Contour(X, Y, Zf, io.Sf("fsz=7, cmapidx=%d"+o.PltArgs, o.PltCmapIdx)) } // plot g clr := "yellow" if o.PltCsimple { clr = "blue" } for _, g := range Zg { plt.ContourSimple(X, Y, g, false, 7, io.Sf("zorder=5, levels=[0], colors=['%s'], linewidths=[%g], clip_on=0", clr, o.PltLwg)) } // plot h clr = "yellow" if o.PltCsimple { clr = "blue" } for _, h := range Zh { plt.ContourSimple(X, Y, h, false, 7, io.Sf("zorder=5, levels=[0], colors=['%s'], linewidths=[%g], clip_on=0", clr, o.PltLwh)) } // initial populations l := "initial population" for _, pop := range o.PopsIni { for _, ind := range pop { x := ind.GetFloats() plt.PlotOne(x[0], x[1], io.Sf("'k.', zorder=20, clip_on=0, label='%s'", l)) l = "" } } // final populations l = "final population" for _, pop := range o.PopsBest { for _, ind := range pop { x := ind.GetFloats() plt.PlotOne(x[0], x[1], io.Sf("'ko', ms=6, zorder=30, clip_on=0, label='%s', markerfacecolor='none'", l)) l = "" } } // extra if o.PltExtra != nil { o.PltExtra() } // best result if o.Nfeasible > 0 { x, _, _, _ := o.find_best() plt.PlotOne(x[0], x[1], "'m*', zorder=50, clip_on=0, label='best', markeredgecolor='m'") } // save figure plt.Cross("clr='grey'") if o.PltAxEqual { plt.Equal() } plt.AxisRange(xmin, xmax, ymin, ymax) plt.Gll("$x_0$", "$x_1$", "leg_out=1, leg_ncol=4, leg_hlen=1.5") plt.SaveD(o.PltDirout, fnkey+".eps") }
func main() { // GA parameters opt := new(goga.Optimiser) opt.Default() opt.Nsol = 6 opt.Ncpu = 1 opt.Tf = 10 opt.EpsH = 1e-3 opt.Verbose = true opt.GenType = "latin" //opt.GenType = "halton" //opt.GenType = "rnd" opt.NormFlt = false opt.UseMesh = true opt.Nbry = 3 // define problem opt.RptName = "9" opt.RptFref = []float64{0.0539498478} opt.RptXref = []float64{-1.717143, 1.595709, 1.827247, -0.7636413, -0.7636450} opt.FltMin = []float64{-2.3, -2.3, -3.2, -3.2, -3.2} opt.FltMax = []float64{+2.3, +2.3, +3.2, +3.2, +3.2} ng, nh := 0, 3 fcn := func(f, g, h, x []float64, ξ []int, cpu int) { f[0] = math.Exp(x[0] * x[1] * x[2] * x[3] * x[4]) h[0] = x[0]*x[0] + x[1]*x[1] + x[2]*x[2] + x[3]*x[3] + x[4]*x[4] - 10.0 h[1] = x[1]*x[2] - 5.0*x[3]*x[4] h[2] = math.Pow(x[0], 3.0) + math.Pow(x[1], 3.0) + 1.0 } // check if false { f := make([]float64, 1) h := make([]float64, 3) fcn(f, nil, h, opt.RptXref, nil, 0) io.Pforan("f(xref) = %g (%g)\n", f[0], opt.RptFref[0]) io.Pforan("h0(xref) = %g\n", h[0]) io.Pforan("h1(xref) = %g\n", h[1]) io.Pforan("h2(xref) = %g\n", h[2]) } // initialise optimiser nf := 1 opt.Init(goga.GenTrialSolutions, nil, fcn, nf, ng, nh) // output function T := make([]float64, opt.Tf+1) // [nT] X := utl.Deep3alloc(opt.Nflt, opt.Nsol, opt.Tf+1) // [nx][nsol][nT] F := utl.Deep3alloc(opt.Nova, opt.Nsol, opt.Tf+1) // [nf][nsol][nT] U := utl.Deep3alloc(opt.Noor, opt.Nsol, opt.Tf+1) // [nu][nsol][nT] opt.Output = func(time int, sols []*goga.Solution) { T[time] = float64(time) for j, s := range sols { for i := 0; i < opt.Nflt; i++ { X[i][j][time] = s.Flt[i] } for i := 0; i < opt.Nova; i++ { F[i][j][time] = s.Ova[i] } for i := 0; i < opt.Noor; i++ { U[i][j][time] = s.Oor[i] } } } // initial population fnk := "one-obj-prob9-dbg" //S0 := opt.GetSolutionsCopy() goga.WriteAllValues("/tmp/goga", fnk, opt) // solve opt.Solve() // print if false { io.Pf("%13s%13s%13s%13s%10s\n", "f0", "u0", "u1", "u2", "feasible") for _, s := range opt.Solutions { io.Pf("%13.5e%13.5e%13.5e%13.5e%10v\n", s.Ova[0], s.Oor[0], s.Oor[1], s.Oor[2], s.Feasible()) } } // plot: time series //a, b := 100, len(T) a, b := 0, 1 //len(T) if false { plt.SetForEps(2.0, 400) nrow := opt.Nflt + opt.Nova + opt.Noor for j := 0; j < opt.Nsol; j++ { for i := 0; i < opt.Nflt; i++ { plt.Subplot(nrow, 1, 1+i) plt.Plot(T[a:b], X[i][j][a:b], "") plt.Gll("$t$", io.Sf("$x_%d$", i), "") } } for j := 0; j < opt.Nsol; j++ { for i := 0; i < opt.Nova; i++ { plt.Subplot(nrow, 1, 1+opt.Nflt+i) plt.Plot(T[a:b], F[i][j][a:b], "") plt.Gll("$t$", io.Sf("$f_%d$", i), "") } } for j := 0; j < opt.Nsol; j++ { for i := 0; i < opt.Noor; i++ { plt.Subplot(nrow, 1, 1+opt.Nflt+opt.Nova+i) plt.Plot(T[a:b], U[i][j][a:b], "") plt.Gll("$t$", io.Sf("$u_%d$", i), "") } } plt.SaveD("/tmp/goga", fnk+"-time.eps") } // plot: x-relationships if true { plt.SetForEps(1, 700) ncol := opt.Nflt - 1 for i := 0; i < opt.Nflt-1; i++ { for j := i + 1; j < opt.Nflt; j++ { plt.Subplot(ncol, ncol, i*ncol+j) if opt.UseMesh { opt.Meshes[i][j].CalcDerived(0) opt.Meshes[i][j].Draw2d(false, false, nil, 0) } for k := 0; k < opt.Nsol; k++ { plt.Plot(X[i][k][a:b], X[j][k][a:b], "ls='none', marker='.'") } plt.Gll(io.Sf("$x_%d$", i), io.Sf("$x_%d$", j), "") } } plt.SaveD("/tmp/goga", fnk+"-x.eps") } }
func plot_spo751(fnkey string) { // constants nidx := 20 // selected node at outer surface didx := 0 // selected dof index for plot nels := 4 // number of elements nips := 4 // number of ips // selected P values for stress plot Psel := []float64{100, 140, 180, 190} tolPsel := 2.0 // tolerance to compare P GPa2MPa := 1000.0 // conversion factor // input data Pcen := 200.0 // [Mpa] a, b := 100.0, 200.0 // [mm], [mm] E, ν := 210000.0, 0.3 // [MPa], [-] σy := 240.0 // [MPa] // analytical solution var sol ana.PressCylin sol.Init([]*fun.Prm{ &fun.Prm{N: "a", V: a}, &fun.Prm{N: "b", V: b}, &fun.Prm{N: "E", V: E}, &fun.Prm{N: "ν", V: ν}, &fun.Prm{N: "σy", V: σy}, }) np := 41 P_ana, Ub_ana := sol.CalcPressDisp(np) R_ana, Sr_ana, St_ana := sol.CalcStresses(Psel, np) // read summary sum := ReadSum(Global.Dirout, Global.Fnkey) // allocate domain distr := false d := NewDomain(Global.Sim.Regions[0], distr) if !d.SetStage(0, Global.Sim.Stages[0], distr) { io.PfRed("plot_spo751: SetStage failed\n") return } // gofem results nto := len(sum.OutTimes) P := make([]float64, nto) Ub := make([]float64, nto) R := utl.Deep3alloc(len(Psel), nels, nips) Sr := utl.Deep3alloc(len(Psel), nels, nips) St := utl.Deep3alloc(len(Psel), nels, nips) i := 0 for tidx, t := range sum.OutTimes { // read results from file if !d.In(sum, tidx, true) { io.PfRed("plot_spo751: cannot read solution\n") return } // collect results for load versus displacement plot nod := d.Nodes[nidx] eq := nod.Dofs[didx].Eq P[tidx] = t * Pcen Ub[tidx] = d.Sol.Y[eq] // stresses if isPsel(Psel, P[tidx], tolPsel) { for j, ele := range d.ElemIntvars { e := ele.(*ElemU) ipsdat := e.OutIpsData() for k, dat := range ipsdat { res := dat.Calc(d.Sol) x, y := dat.X[0], dat.X[1] sx := res["sx"] * GPa2MPa sy := res["sy"] * GPa2MPa sxy := res["sxy"] * GPa2MPa / math.Sqrt2 R[i][j][k], Sr[i][j][k], St[i][j][k], _ = ana.PolarStresses(x, y, sx, sy, sxy) } } i++ } } // auxiliary data for plotting stresses colors := []string{"r", "m", "g", "k", "y", "c", "r", "m"} markers1 := []string{"o", "s", "x", ".", "^", "*", "o", "s"} markers2 := []string{"+", "+", "+", "+", "+", "+", "+", "+"} // plot load displacements plt.SetForEps(0.8, 300) if true { //if false { plt.Plot(Ub_ana, P_ana, "'b-', ms=2, label='solution', clip_on=0") plt.Plot(Ub, P, "'r.--', label='fem: outer', clip_on=0") plt.Gll("$u_x\\;\\mathrm{[mm]}$", "$P\\;\\mathrm{[MPa]}$", "") plt.SaveD("/tmp", io.Sf("gofem_%s_disp.eps", fnkey)) } // plot radial stresses if true { //if false { plt.Reset() for i, Pval := range Psel { plt.Plot(R_ana, Sr_ana[i], "'b-'") for k := 0; k < nips; k++ { for j := 0; j < nels; j++ { args := io.Sf("'%s%s'", colors[i], markers1[i]) if k > 1 { args = io.Sf("'k%s', ms=10", markers2[i]) } if k == 0 && j == 0 { args += io.Sf(", label='P=%g'", Pval) } plt.PlotOne(R[i][j][k], Sr[i][j][k], args) } } } plt.Gll("$r\\;\\mathrm{[mm]}$", "$\\sigma_r\\;\\mathrm{[MPa]}$", "leg_loc='lower right'") plt.AxisXrange(a, b) plt.SaveD("/tmp", io.Sf("gofem_%s_sr.eps", fnkey)) } // plot tangential stresses if true { //if false { plt.Reset() for i, Pval := range Psel { plt.Plot(R_ana, St_ana[i], "'b-'") for k := 0; k < nips; k++ { for j := 0; j < nels; j++ { args := io.Sf("'%s%s'", colors[i], markers1[i]) if k > 1 { args = io.Sf("'k%s', ms=10", markers2[i]) } if k == 0 && j == 0 { args += io.Sf(", label='P=%g'", Pval) } plt.PlotOne(R[i][j][k], St[i][j][k], args) } } } plt.Gll("$r\\;\\mathrm{[mm]}$", "$\\sigma_t\\;\\mathrm{[MPa]}$", "leg_loc='upper left'") plt.SaveD("/tmp", io.Sf("gofem_%s_st.eps", fnkey)) } }
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 } }
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_flt03(tst *testing.T) { //verbose() chk.PrintTitle("flt03. sin⁶(5 π x) multimodal") // configuration C := NewConfParams() C.Nova = 1 C.Noor = 2 C.Nisl = 4 C.Ninds = 24 C.GAtype = "crowd" C.DiffEvol = true C.CrowdSize = 3 C.ParetoPhi = 0.01 C.CompProb = true C.Tf = 100 C.Dtmig = 60 C.RangeFlt = [][]float64{{0, 0.9999999999999}} C.PopFltGen = PopFltGen C.CalcDerived() rnd.Init(C.Seed) // post-processing function values := utl.Deep3alloc(C.Tf/10, C.Nisl, C.Ninds) C.PostProc = func(idIsland, time int, pop Population) { if time%10 == 0 { k := time / 10 for i, ind := range pop { values[k][idIsland][i] = ind.GetFloat(0) } } } // functions yfcn := func(x float64) float64 { return math.Pow(math.Sin(5.0*math.Pi*x), 6.0) } fcn := func(f, g, h []float64, x []float64) { f[0] = -yfcn(x[0]) } // simple problem sim := NewSimpleFltProb(fcn, 1, 0, 0, C) sim.Run(chk.Verbose) // write histograms and plot if chk.Verbose { // write histograms var buf bytes.Buffer hist := rnd.Histogram{Stations: utl.LinSpace(0, 1, 13)} for k := 0; k < C.Tf/10; k++ { for i := 0; i < C.Nisl; i++ { clear := false if i == 0 { clear = true } hist.Count(values[k][i], clear) } io.Ff(&buf, "\ntime=%d\n%v", k*10, rnd.TextHist(hist.GenLabels("%4.2f"), hist.Counts, 60)) } io.WriteFileVD("/tmp/goga", "test_flt03_hist.txt", &buf) // plot plt.SetForEps(0.8, 300) xmin := sim.Evo.Islands[0].Pop[0].GetFloat(0) xmax := xmin for k := 0; k < C.Nisl; k++ { for _, ind := range sim.Evo.Islands[k].Pop { x := ind.GetFloat(0) y := yfcn(x) xmin = utl.Min(xmin, x) xmax = utl.Max(xmax, x) plt.PlotOne(x, y, "'r.',clip_on=0,zorder=20") } } np := 401 X := utl.LinSpace(0, 1, np) Y := make([]float64, np) for i := 0; i < np; i++ { Y[i] = yfcn(X[i]) } plt.Plot(X, Y, "'b-',clip_on=0,zorder=10") plt.Gll("$x$", "$y$", "") plt.SaveD("/tmp/goga", "test_flt03_func.eps") } }
// PlotContour plots contour func (o *Optimiser) PlotContour(iFlt, jFlt, iOva int, pp *PlotParams) { // check var x []float64 if pp.Refx == nil { if iFlt > 1 || jFlt > 1 { chk.Panic("Refx vector must be given to PlotContour when iFlt or jFlt > 1") } x = make([]float64, 2) } else { x = make([]float64, len(pp.Refx)) copy(x, pp.Refx) } // limits and meshgrid xmin, xmax := o.FltMin[iFlt], o.FltMax[iFlt] ymin, ymax := o.FltMin[jFlt], o.FltMax[jFlt] if pp.Xrange != nil { xmin, xmax = pp.Xrange[0], pp.Xrange[1] } if pp.Yrange != nil { ymin, ymax = pp.Yrange[0], pp.Yrange[1] } // check objective function var sol *Solution // copy of solution for objective function if o.MinProb == nil { pp.NoG = true pp.NoH = true sol = NewSolution(o.Nsol, 0, &o.Parameters) o.Solutions[0].CopyInto(sol) if pp.Refx != nil { copy(sol.Flt, pp.Refx) } } // auxiliary variables X, Y := utl.MeshGrid2D(xmin, xmax, ymin, ymax, pp.Npts, pp.Npts) var Zf [][]float64 var Zg [][][]float64 var Zh [][][]float64 var Za [][]float64 if !pp.NoF { Zf = utl.DblsAlloc(pp.Npts, pp.Npts) } if o.Ng > 0 && !pp.NoG { Zg = utl.Deep3alloc(o.Ng, pp.Npts, pp.Npts) } if o.Nh > 0 && !pp.NoH { Zh = utl.Deep3alloc(o.Nh, pp.Npts, pp.Npts) } if pp.WithAux { Za = utl.DblsAlloc(pp.Npts, pp.Npts) } // compute values grp := 0 for i := 0; i < pp.Npts; i++ { for j := 0; j < pp.Npts; j++ { x[iFlt], x[jFlt] = X[i][j], Y[i][j] if o.MinProb == nil { copy(sol.Flt, x) o.ObjFunc(sol, grp) if !pp.NoF { Zf[i][j] = sol.Ova[iOva] } if pp.WithAux { Za[i][j] = sol.Aux } } else { o.MinProb(o.F[grp], o.G[grp], o.H[grp], x, nil, grp) if !pp.NoF { Zf[i][j] = o.F[grp][iOva] } if !pp.NoG { for k, g := range o.G[grp] { Zg[k][i][j] = g } } if !pp.NoH { for k, h := range o.H[grp] { Zh[k][i][j] = h } } } } } // plot f if !pp.NoF && !pp.OnlyAux { txt := "cbar=0" if pp.Cbar { txt = "" } if pp.Simple { plt.ContourSimple(X, Y, Zf, true, 7, io.Sf("colors=['%s'], fsz=7, %s", pp.FmtF.C, txt)) } else { plt.Contour(X, Y, Zf, io.Sf("fsz=7, cmapidx=%d, %s", pp.CmapIdx, txt)) } } // plot g if !pp.NoG && !pp.OnlyAux { for _, g := range Zg { plt.ContourSimple(X, Y, g, false, 7, io.Sf("zorder=5, levels=[0], colors=['%s'], linewidths=[%g], clip_on=0", pp.FmtG.C, pp.FmtG.Lw)) } } // plot h if !pp.NoH && !pp.OnlyAux { for i, h := range Zh { if i == pp.IdxH || pp.IdxH < 0 { plt.ContourSimple(X, Y, h, false, 7, io.Sf("zorder=5, levels=[0], colors=['%s'], linewidths=[%g], clip_on=0", pp.FmtH.C, pp.FmtH.Lw)) } } } // plot aux if pp.WithAux { if pp.OnlyAux { txt := "cbar=0" if pp.Cbar { txt = "" } if pp.Simple { plt.ContourSimple(X, Y, Za, true, 7, io.Sf("colors=['%s'], fsz=7, %s", pp.FmtF.C, txt)) } else { plt.Contour(X, Y, Za, io.Sf("fsz=7, markZero='red', cmapidx=%d, %s", pp.CmapIdx, txt)) } } else { plt.ContourSimple(X, Y, Za, false, 7, io.Sf("zorder=5, levels=[0], colors=['%s'], linewidths=[%g], clip_on=0", pp.FmtA.C, pp.FmtA.Lw)) } } // limits if pp.Limits { plt.Plot( []float64{o.FltMin[iFlt], o.FltMax[iFlt], o.FltMax[iFlt], o.FltMin[iFlt], o.FltMin[iFlt]}, []float64{o.FltMin[jFlt], o.FltMin[jFlt], o.FltMax[jFlt], o.FltMax[jFlt], o.FltMin[jFlt]}, "'y--', color='yellow', zorder=10", ) } }