// PlotDeriv plots derivative dR[i][j][k]du[d] (2D only) // option = 0 : use CalcBasisAndDerivs // 1 : use NumericalDeriv func (o *Nurbs) PlotDeriv(l, d int, args string, npts, option int) { lbls := []string{"N\\&dN", "numD"} switch o.gnd { // curve case 1: // surface case 2: xx := la.MatAlloc(npts, npts) yy := la.MatAlloc(npts, npts) zz := la.MatAlloc(npts, npts) du0 := (o.b[0].tmax - o.b[0].tmin) / float64(npts-1) du1 := (o.b[1].tmax - o.b[1].tmin) / float64(npts-1) drdu := make([]float64, 2) for m := 0; m < npts; m++ { u0 := o.b[0].tmin + float64(m)*du0 for n := 0; n < npts; n++ { u1 := o.b[1].tmin + float64(n)*du1 u := []float64{u0, u1} x := o.Point(u) xx[m][n] = x[0] yy[m][n] = x[1] switch option { case 0: o.CalcBasisAndDerivs(u) o.GetDerivL(drdu, l) case 1: o.NumericalDeriv(drdu, u, l) } zz[m][n] = drdu[d] } } plt.Title(io.Sf("%d,%d:%s", l, d, lbls[option]), "size=10") plt.Contour(xx, yy, zz, "fsz=8") } }
// 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") }
// PlotBasis plots basis function (2D only) // option = 0 : use CalcBasis // 1 : use CalcBasisAndDerivs // 2 : use RecursiveBasis func (o *Nurbs) PlotBasis(l int, args string, npts, option int) { lbls := []string{"CalcBasis function", "CalcBasisAndDerivs function", "RecursiveBasis function"} switch o.gnd { // curve case 1: U := make([]float64, npts) S := make([]float64, npts) du := (o.b[0].tmax - o.b[0].tmin) / float64(npts-1) uvec := []float64{0} for m := 0; m < npts; m++ { U[m] = o.b[0].tmin + float64(m)*du uvec[0] = U[m] switch option { case 0: o.CalcBasis(uvec) S[m] = o.GetBasisL(l) case 1: o.CalcBasisAndDerivs(uvec) S[m] = o.GetBasisL(l) case 2: S[m] = o.RecursiveBasis(uvec, l) } } plt.Plot(U, S, args) plt.Gll("$u$", io.Sf("$S_%d$", l), "") // surface case 2: xx := la.MatAlloc(npts, npts) yy := la.MatAlloc(npts, npts) zz := la.MatAlloc(npts, npts) du0 := (o.b[0].tmax - o.b[0].tmin) / float64(npts-1) du1 := (o.b[1].tmax - o.b[1].tmin) / float64(npts-1) for m := 0; m < npts; m++ { u0 := o.b[0].tmin + float64(m)*du0 for n := 0; n < npts; n++ { u1 := o.b[1].tmin + float64(n)*du1 u := []float64{u0, u1} x := o.Point(u) xx[m][n] = x[0] yy[m][n] = x[1] switch option { case 0: o.CalcBasis(u) zz[m][n] = o.GetBasisL(l) case 1: o.CalcBasisAndDerivs(u) zz[m][n] = o.GetBasisL(l) case 2: zz[m][n] = o.RecursiveBasis(u, l) } } } plt.Contour(xx, yy, zz, "fsz=7") } plt.Title(io.Sf("%s @ %d", lbls[option], l), "size=7") }
// PlotBasis plots basis function (2D only) // option = 0 : use CalcBasis // 1 : use CalcBasisAndDerivs // 2 : use RecursiveBasis func (o *Nurbs) PlotBasis(l int, args string, npts, option int) { lbls := []string{"Nonly", "N\\&dN", "recN"} switch o.gnd { // curve case 1: xx := make([]float64, npts) yy := make([]float64, npts) du0 := (o.b[0].tmax - o.b[0].tmin) / float64(npts-1) for m := 0; m < npts; m++ { u0 := o.b[0].tmin + float64(m)*du0 u := []float64{u0} x := o.Point(u) xx[m] = x[0] switch option { case 0: o.CalcBasis(u) yy[m] = o.GetBasisL(l) case 1: o.CalcBasisAndDerivs(u) yy[m] = o.GetBasisL(l) case 2: yy[m] = o.RecursiveBasis(u, l) } } plt.Plot(xx, yy, "fsz=8") // surface case 2: xx := la.MatAlloc(npts, npts) yy := la.MatAlloc(npts, npts) zz := la.MatAlloc(npts, npts) du0 := (o.b[0].tmax - o.b[0].tmin) / float64(npts-1) du1 := (o.b[1].tmax - o.b[1].tmin) / float64(npts-1) for m := 0; m < npts; m++ { u0 := o.b[0].tmin + float64(m)*du0 for n := 0; n < npts; n++ { u1 := o.b[1].tmin + float64(n)*du1 u := []float64{u0, u1} x := o.Point(u) xx[m][n] = x[0] yy[m][n] = x[1] switch option { case 0: o.CalcBasis(u) zz[m][n] = o.GetBasisL(l) case 1: o.CalcBasisAndDerivs(u) zz[m][n] = o.GetBasisL(l) case 2: zz[m][n] = o.RecursiveBasis(u, l) } } } plt.Contour(xx, yy, zz, "fsz=8") } plt.Title(io.Sf("%d:%s", l, lbls[option]), "size=10") }
// PlotDeriv plots derivative dR[i][j][k]du[d] (2D only) // option = 0 : use CalcBasisAndDerivs // 1 : use NumericalDeriv func (o *Nurbs) PlotDeriv(l, d int, args string, npts, option int) { lbls := []string{"CalcBasisAndDerivs function", "NumericalDeriv function"} switch o.gnd { // curve case 1: U := make([]float64, npts) G := make([]float64, npts) du := (o.b[0].tmax - o.b[0].tmin) / float64(npts-1) uvec := []float64{0} gvec := []float64{0} for m := 0; m < npts; m++ { U[m] = o.b[0].tmin + float64(m)*du uvec[0] = U[m] switch option { case 0: o.CalcBasisAndDerivs(uvec) o.GetDerivL(gvec, l) case 1: o.NumericalDeriv(gvec, uvec, l) } G[m] = gvec[0] } plt.Plot(U, G, args) plt.Gll("$u$", io.Sf("$G_%d$", l), "") // surface case 2: xx := la.MatAlloc(npts, npts) yy := la.MatAlloc(npts, npts) zz := la.MatAlloc(npts, npts) du0 := (o.b[0].tmax - o.b[0].tmin) / float64(npts-1) du1 := (o.b[1].tmax - o.b[1].tmin) / float64(npts-1) drdu := make([]float64, 2) for m := 0; m < npts; m++ { u0 := o.b[0].tmin + float64(m)*du0 for n := 0; n < npts; n++ { u1 := o.b[1].tmin + float64(n)*du1 u := []float64{u0, u1} x := o.Point(u) xx[m][n] = x[0] yy[m][n] = x[1] switch option { case 0: o.CalcBasisAndDerivs(u) o.GetDerivL(drdu, l) case 1: o.NumericalDeriv(drdu, u, l) } zz[m][n] = drdu[d] } } plt.Contour(xx, yy, zz, "fsz=7") } plt.Title(io.Sf("%s @ %d,%d", lbls[option], l, d), "size=7") }
func CTPplotter(θ, a, b, c, d, e, f1max float64) func() { return func() { np := 401 X, Y := utl.MeshGrid2D(0, 1, 0, f1max, np, np) Z1 := utl.DblsAlloc(np, np) Z2 := utl.DblsAlloc(np, np) sθ, cθ := math.Sin(θ), math.Cos(θ) for j := 0; j < np; j++ { for i := 0; i < np; i++ { f0, f1 := X[i][j], Y[i][j] Z1[i][j] = cθ*(f1-e) - sθ*f0 Z2[i][j] = CTPconstraint(θ, a, b, c, d, e, X[i][j], Y[i][j]) } } plt.Contour(X, Y, Z2, "levels=[0,2],cbar=0,lwd=0.5,fsz=5,cmapidx=6") plt.ContourSimple(X, Y, Z1, false, 7, "linestyles=['--'], linewidths=[0.7], colors=['b'], levels=[0]") } }
// Run computes β starting witn an initial guess func (o *ReliabFORM) Run(βtrial float64, verbose bool, args ...interface{}) (β float64, μ, σ, x []float64) { // initial random variables β = βtrial nx := len(o.μ) μ = make([]float64, nx) // mean values (equivalent normal value) σ = make([]float64, nx) // deviation values (equivalent normal value) x = make([]float64, nx) // current vector of random variables defining min(β) for i := 0; i < nx; i++ { μ[i] = o.μ[i] σ[i] = o.σ[i] x[i] = o.μ[i] } // lognormal distribution structure var lnd DistLogNormal // has lognormal random variable? haslrv := false for _, found := range o.lrv { if found { haslrv = true break } } // function to compute β with x-constant // gβ(β) = g(μ - β・A・σ) = 0 var err error gβfcn := func(fy, y []float64) error { βtmp := y[0] for i := 0; i < nx; i++ { o.xtmp[i] = μ[i] - βtmp*o.α[i]*σ[i] } fy[0], err = o.gfcn(o.xtmp, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", o.xtmp, err) } return nil } // derivative of gβ w.r.t β hβfcn := func(dfdy [][]float64, y []float64) error { βtmp := y[0] for i := 0; i < nx; i++ { o.xtmp[i] = μ[i] - βtmp*o.α[i]*σ[i] } err = o.hfcn(o.dgdx, o.xtmp, args) if err != nil { chk.Panic("cannot compute hfcn(%v):\n%v", o.xtmp, err) } dfdy[0][0] = 0 for i := 0; i < nx; i++ { dfdy[0][0] -= o.dgdx[i] * o.α[i] * σ[i] } return nil } // nonlinear solver with y[0] = β // solving: gβ(β) = g(μ - β・A・σ) = 0 var nls num.NlSolver nls.Init(1, gβfcn, nil, hβfcn, true, false, nil) defer nls.Clean() // message if verbose { io.Pf("\n%s", io.StrThickLine(60)) } // plotting plot := o.PlotFnk != "" if nx != 2 { plot = false } if plot { if o.PlotNp < 3 { o.PlotNp = 41 } var umin, umax, vmin, vmax float64 if o.PlotCf < 1 { o.PlotCf = 2 } if len(o.PlotUrange) == 0 { umin, umax = μ[0]-o.PlotCf*μ[0], μ[0]+o.PlotCf*μ[0] vmin, vmax = μ[1]-o.PlotCf*μ[1], μ[1]+o.PlotCf*μ[1] } else { chk.IntAssert(len(o.PlotUrange), 2) chk.IntAssert(len(o.PlotVrange), 2) umin, umax = o.PlotUrange[0], o.PlotUrange[1] vmin, vmax = o.PlotVrange[0], o.PlotVrange[1] } o.PlotU, o.PlotV = utl.MeshGrid2D(umin, umax, vmin, vmax, o.PlotNp, o.PlotNp) o.PlotZ = la.MatAlloc(o.PlotNp, o.PlotNp) plt.SetForEps(0.8, 300) for i := 0; i < o.PlotNp; i++ { for j := 0; j < o.PlotNp; j++ { o.xtmp[0] = o.PlotU[i][j] o.xtmp[1] = o.PlotV[i][j] o.PlotZ[i][j], err = o.gfcn(o.xtmp, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", x, err) } } } plt.Contour(o.PlotU, o.PlotV, o.PlotZ, "") plt.ContourSimple(o.PlotU, o.PlotV, o.PlotZ, true, 8, "levels=[0], colors=['yellow']") plt.PlotOne(x[0], x[1], "'ro', label='initial'") } // iterations to find β var dat VarData B := []float64{β} itB := 0 for itB = 0; itB < o.NmaxItB; itB++ { // message if verbose { gx, err := o.gfcn(x, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", x, err) } io.Pf("%s itB=%d β=%g g=%g\n", io.StrThinLine(60), itB, β, gx) } // plot if plot { plt.PlotOne(x[0], x[1], "'r.'") } // compute direction cosines itA := 0 for itA = 0; itA < o.NmaxItA; itA++ { // has lognormal random variable (lrv) if haslrv { // find equivalent normal mean and std deviation for lognormal variables for i := 0; i < nx; i++ { if o.lrv[i] { // set distribution dat.M, dat.S = o.μ[i], o.σ[i] lnd.Init(&dat) // update μ and σ fx := lnd.Pdf(x[i]) Φinvx := (math.Log(x[i]) - lnd.M) / lnd.S φx := math.Exp(-Φinvx*Φinvx/2.0) / math.Sqrt2 / math.SqrtPi σ[i] = φx / fx μ[i] = x[i] - Φinvx*σ[i] } } } // compute direction cosines err = o.hfcn(o.dgdx, x, args) if err != nil { chk.Panic("cannot compute hfcn(%v):\n%v", x, err) } den := 0.0 for i := 0; i < nx; i++ { den += math.Pow(o.dgdx[i]*σ[i], 2.0) } den = math.Sqrt(den) αerr := 0.0 // difference on α for i := 0; i < nx; i++ { αnew := o.dgdx[i] * σ[i] / den αerr += math.Pow(αnew-o.α[i], 2.0) o.α[i] = αnew } αerr = math.Sqrt(αerr) // message if verbose { io.Pf(" itA=%d\n", itA) io.Pf("%12s%12s%12s%12s\n", "x", "μ", "σ", "α") for i := 0; i < nx; i++ { io.Pf("%12.3f%12.3f%12.3f%12.3f\n", x[i], μ[i], σ[i], o.α[i]) } } // update x-star for i := 0; i < nx; i++ { x[i] = μ[i] - β*o.α[i]*σ[i] } // check convergence on α if itA > 1 && αerr < o.TolA { if verbose { io.Pfgrey(". . . converged on α with αerr=%g . . .\n", αerr) } break } } // failed to converge on α if itA == o.NmaxItA { chk.Panic("failed to convege on α") } // compute new β B[0] = β nls.Solve(B, o.NlsSilent) βerr := math.Abs(B[0] - β) β = B[0] if o.NlsCheckJ { nls.CheckJ(B, o.NlsCheckJtol, true, false) } // update x-star for i := 0; i < nx; i++ { x[i] = μ[i] - β*o.α[i]*σ[i] } // check convergence on β if βerr < o.TolB { if verbose { io.Pfgrey2(". . . converged on β with βerr=%g . . .\n", βerr) } break } } // failed to converge on β if itB == o.NmaxItB { chk.Panic("failed to converge on β") } // message if verbose { gx, err := o.gfcn(x, args) if err != nil { chk.Panic("cannot compute gfcn(%v):\n%v", x, err) } io.Pfgreen("x = %v\n", x) io.Pfgreen("g = %v\n", gx) io.PfGreen("β = %v\n", β) } // plot if plot { plt.Gll("$x_0$", "$x_1$", "") plt.Cross("") plt.SaveD("/tmp/gosl", "fig_form_"+o.PlotFnk+".eps") } 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") }
// PlotX plots F and the gradient of F, Gx and Gy, for varying x and fixed t // hlZero -- highlight F(t,x) = 0 // axEqual -- use axis['equal'] func PlotX(o Func, dirout, fname string, tcte float64, xmin, xmax []float64, np int, args string, withGrad, hlZero, axEqual, save, show bool, extra func()) { if len(xmin) == 3 { chk.Panic("PlotX works in 2D only") } X, Y := utl.MeshGrid2D(xmin[0], xmax[0], xmin[1], xmax[1], np, np) F := la.MatAlloc(np, np) var Gx, Gy [][]float64 nrow := 1 if withGrad { Gx = la.MatAlloc(np, np) Gy = la.MatAlloc(np, np) nrow += 1 } x := make([]float64, 2) g := make([]float64, 2) for i := 0; i < np; i++ { for j := 0; j < np; j++ { x[0], x[1] = X[i][j], Y[i][j] F[i][j] = o.F(tcte, x) if withGrad { o.Grad(g, tcte, x) Gx[i][j] = g[0] Gy[i][j] = g[1] } } } prop, wid, dpi := 1.0, 600.0, 200 os.MkdirAll(dirout, 0777) if withGrad { prop = 2 plt.SetForPng(prop, wid, dpi) plt.Subplot(nrow, 1, 1) plt.Title("F(t,x)", "") } else { plt.SetForPng(prop, wid, dpi) } plt.Contour(X, Y, F, args) if hlZero { plt.ContourSimple(X, Y, F, false, 8, "levels=[0], linewidths=[2], colors=['yellow']") } if axEqual { plt.Equal() } if extra != nil { extra() } plt.Gll("x", "y", "") if withGrad { plt.Subplot(2, 1, 2) plt.Title("gradient", "") plt.Quiver(X, Y, Gx, Gy, args) if axEqual { plt.Equal() } plt.Gll("x", "y", "") } if save { plt.Save(dirout + "/" + fname) } if show { plt.Show() } }
func solve_problem(problem int) (opt *goga.Optimiser) { io.Pf("\n\n------------------------------------- problem = %d ---------------------------------------\n", problem) // parameters opt = new(goga.Optimiser) opt.Default() opt.Ncpu = 3 opt.Tf = 500 opt.Verbose = false opt.Nsamples = 1000 opt.GenType = "latin" opt.DEC = 0.1 // options for report opt.HistNsta = 6 opt.HistLen = 13 opt.RptFmtE = "%.4e" opt.RptFmtL = "%.4e" opt.RptFmtEdev = "%.3e" opt.RptFmtLdev = "%.3e" // problem variables nx := 10 opt.RptName = io.Sf("CTP%d", problem) opt.Nsol = 120 opt.FltMin = make([]float64, nx) opt.FltMax = make([]float64, nx) for i := 0; i < nx; i++ { opt.FltMin[i] = 0 opt.FltMax[i] = 1 } nf, ng, nh := 2, 1, 0 // extra problem variables var f1max float64 var fcn goga.MinProb_t var extraplot func() // problems switch problem { // problem # 0 -- TNK case 0: ng = 2 f1max = 1.21 opt.RptName = "TNK" opt.FltMin = []float64{0, 0} opt.FltMax = []float64{PI, PI} fcn = func(f, g, h, x []float64, ξ []int, cpu int) { f[0] = x[0] f[1] = x[1] g[0] = x[0]*x[0] + x[1]*x[1] - 1.0 - 0.1*math.Cos(16.0*math.Atan2(x[0], x[1])) g[1] = 0.5 - math.Pow(x[0]-0.5, 2.0) - math.Pow(x[1]-0.5, 2.0) } extraplot = func() { np := 301 X, Y := utl.MeshGrid2D(0, 1.3, 0, 1.3, np, np) Z1, Z2, Z3 := utl.DblsAlloc(np, np), utl.DblsAlloc(np, np), utl.DblsAlloc(np, np) for j := 0; j < np; j++ { for i := 0; i < np; i++ { g1 := 0.5 - math.Pow(X[i][j]-0.5, 2.0) - math.Pow(Y[i][j]-0.5, 2.0) if g1 >= 0 { Z1[i][j] = X[i][j]*X[i][j] + Y[i][j]*Y[i][j] - 1.0 - 0.1*math.Cos(16.0*math.Atan2(Y[i][j], X[i][j])) } else { Z1[i][j] = -1 } Z2[i][j] = X[i][j]*X[i][j] + Y[i][j]*Y[i][j] - 1.0 - 0.1*math.Cos(16.0*math.Atan2(Y[i][j], X[i][j])) Z3[i][j] = g1 } } plt.Contour(X, Y, Z1, "levels=[0,2],cbar=0,lwd=0.5,fsz=5,cmapidx=6") plt.Text(0.3, 0.95, "0.000", "size=5,rotation=10") plt.ContourSimple(X, Y, Z2, false, 7, "linestyles=['-'], linewidths=[0.7], colors=['k'], levels=[0]") plt.ContourSimple(X, Y, Z3, false, 7, "linestyles=['-'], linewidths=[1.0], colors=['k'], levels=[0]") } opt.Multi_fcnErr = func(f []float64) float64 { return f[0]*f[0] + f[1]*f[1] - 1.0 - 0.1*math.Cos(16.0*math.Atan2(f[0], f[1])) } // problem # 1 -- CTP1, Deb 2001, p367, fig 225 case 1: ng = 2 f1max = 1.0 a0, b0 := 0.858, 0.541 a1, b1 := 0.728, 0.295 fcn = func(f, g, h, x []float64, ξ []int, cpu int) { c0 := 1.0 for i := 1; i < len(x); i++ { c0 += x[i] } f[0] = x[0] f[1] = c0 * math.Exp(-x[0]/c0) if true { g[0] = f[1] - a0*math.Exp(-b0*f[0]) g[1] = f[1] - a1*math.Exp(-b1*f[0]) } } f0a := math.Log(a0) / (b0 - 1.0) f1a := math.Exp(-f0a) f0b := math.Log(a0/a1) / (b0 - b1) f1b := a0 * math.Exp(-b0*f0b) opt.Multi_fcnErr = func(f []float64) float64 { if f[0] < f0a { return f[1] - math.Exp(-f[0]) } if f[0] < f0b { return f[1] - a0*math.Exp(-b0*f[0]) } return f[1] - a1*math.Exp(-b1*f[0]) } extraplot = func() { np := 201 X, Y := utl.MeshGrid2D(0, 1, 0, 1, np, np) Z := utl.DblsAlloc(np, np) for j := 0; j < np; j++ { for i := 0; i < np; i++ { Z[i][j] = opt.Multi_fcnErr([]float64{X[i][j], Y[i][j]}) } } plt.Contour(X, Y, Z, "levels=[0,0.6],cbar=0,lwd=0.5,fsz=5,cmapidx=6") F0 := utl.LinSpace(0, 1, 21) F1r := make([]float64, len(F0)) F1s := make([]float64, len(F0)) F1t := make([]float64, len(F0)) for i, f0 := range F0 { F1r[i] = math.Exp(-f0) F1s[i] = a0 * math.Exp(-b0*f0) F1t[i] = a1 * math.Exp(-b1*f0) } plt.Plot(F0, F1r, "'k--',color='blue'") plt.Plot(F0, F1s, "'k--',color='green'") plt.Plot(F0, F1t, "'k--',color='gray'") plt.PlotOne(f0a, f1a, "'k|', ms=20") plt.PlotOne(f0b, f1b, "'k|', ms=20") } // problem # 2 -- CTP2, Deb 2001, p368/369, fig 226 case 2: f1max = 1.2 θ, a, b := -0.2*PI, 0.2, 10.0 c, d, e := 1.0, 6.0, 1.0 fcn = CTPgenerator(θ, a, b, c, d, e) extraplot = CTPplotter(θ, a, b, c, d, e, f1max) opt.Multi_fcnErr = CTPerror1(θ, a, b, c, d, e) // problem # 3 -- CTP3, Deb 2001, p368/370, fig 227 case 3: f1max = 1.2 θ, a, b := -0.2*PI, 0.1, 10.0 c, d, e := 1.0, 0.5, 1.0 fcn = CTPgenerator(θ, a, b, c, d, e) extraplot = CTPplotter(θ, a, b, c, d, e, f1max) opt.Multi_fcnErr = CTPerror1(θ, a, b, c, d, e) // problem # 4 -- CTP4, Deb 2001, p368/370, fig 228 case 4: f1max = 2.0 θ, a, b := -0.2*PI, 0.75, 10.0 c, d, e := 1.0, 0.5, 1.0 fcn = CTPgenerator(θ, a, b, c, d, e) extraplot = CTPplotter(θ, a, b, c, d, e, f1max) opt.Multi_fcnErr = CTPerror1(θ, a, b, c, d, e) // problem # 5 -- CTP5, Deb 2001, p368/371, fig 229 case 5: f1max = 1.2 θ, a, b := -0.2*PI, 0.1, 10.0 c, d, e := 2.0, 0.5, 1.0 fcn = CTPgenerator(θ, a, b, c, d, e) extraplot = CTPplotter(θ, a, b, c, d, e, f1max) opt.Multi_fcnErr = CTPerror1(θ, a, b, c, d, e) // problem # 6 -- CTP6, Deb 2001, p368/372, fig 230 case 6: f1max = 5.0 θ, a, b := 0.1*PI, 40.0, 0.5 c, d, e := 1.0, 2.0, -2.0 fcn = CTPgenerator(θ, a, b, c, d, e) extraplot = func() { np := 201 X, Y := utl.MeshGrid2D(0, 1, 0, 20, np, np) Z := utl.DblsAlloc(np, np) for j := 0; j < np; j++ { for i := 0; i < np; i++ { Z[i][j] = CTPconstraint(θ, a, b, c, d, e, X[i][j], Y[i][j]) } } plt.Contour(X, Y, Z, "levels=[-30,-15,0,15,30],cbar=0,lwd=0.5,fsz=5,cmapidx=6") } opt.Multi_fcnErr = CTPerror1(θ, a, b, c, d, e) // problem # 7 -- CTP7, Deb 2001, p368/373, fig 231 case 7: f1max = 1.2 θ, a, b := -0.05*PI, 40.0, 5.0 c, d, e := 1.0, 6.0, 0.0 fcn = CTPgenerator(θ, a, b, c, d, e) opt.Multi_fcnErr = func(f []float64) float64 { return f[1] - (1.0 - f[0]) } extraplot = func() { np := 201 X, Y := utl.MeshGrid2D(0, 1, 0, f1max, np, np) Z1 := utl.DblsAlloc(np, np) Z2 := utl.DblsAlloc(np, np) for j := 0; j < np; j++ { for i := 0; i < np; i++ { Z1[i][j] = opt.Multi_fcnErr([]float64{X[i][j], Y[i][j]}) Z2[i][j] = CTPconstraint(θ, a, b, c, d, e, X[i][j], Y[i][j]) } } plt.Contour(X, Y, Z2, "levels=[0,3],cbar=0,lwd=0.5,fsz=5,cmapidx=6") plt.ContourSimple(X, Y, Z1, false, 7, "linestyles=['--'], linewidths=[0.7], colors=['b'], levels=[0]") } // problem # 8 -- CTP8, Deb 2001, p368/373, fig 232 case 8: ng = 2 f1max = 5.0 θ1, a, b := 0.1*PI, 40.0, 0.5 c, d, e := 1.0, 2.0, -2.0 θ2, A, B := -0.05*PI, 40.0, 2.0 C, D, E := 1.0, 6.0, 0.0 sin1, cos1 := math.Sin(θ1), math.Cos(θ1) sin2, cos2 := math.Sin(θ2), math.Cos(θ2) fcn = func(f, g, h, x []float64, ξ []int, cpu int) { c0 := 1.0 for i := 1; i < len(x); i++ { c0 += x[i] } f[0] = x[0] f[1] = c0 * (1.0 - f[0]/c0) if true { c1 := cos1*(f[1]-e) - sin1*f[0] c2 := sin1*(f[1]-e) + cos1*f[0] c3 := math.Sin(b * PI * math.Pow(c2, c)) g[0] = c1 - a*math.Pow(math.Abs(c3), d) d1 := cos2*(f[1]-E) - sin2*f[0] d2 := sin2*(f[1]-E) + cos2*f[0] d3 := math.Sin(B * PI * math.Pow(d2, C)) g[1] = d1 - A*math.Pow(math.Abs(d3), D) } } extraplot = func() { np := 401 X, Y := utl.MeshGrid2D(0, 1, 0, 20, np, np) Z1 := utl.DblsAlloc(np, np) Z2 := utl.DblsAlloc(np, np) Z3 := utl.DblsAlloc(np, np) for j := 0; j < np; j++ { for i := 0; i < np; i++ { c1 := cos1*(Y[i][j]-e) - sin1*X[i][j] c2 := sin1*(Y[i][j]-e) + cos1*X[i][j] c3 := math.Sin(b * PI * math.Pow(c2, c)) d1 := cos2*(Y[i][j]-E) - sin2*X[i][j] d2 := sin2*(Y[i][j]-E) + cos2*X[i][j] d3 := math.Sin(B * PI * math.Pow(d2, C)) Z1[i][j] = c1 - a*math.Pow(math.Abs(c3), d) Z2[i][j] = d1 - A*math.Pow(math.Abs(d3), D) if Z1[i][j] >= 0 && Z2[i][j] >= 0 { Z3[i][j] = 1 } else { Z3[i][j] = -1 } } } plt.Contour(X, Y, Z3, "colors=['white','gray'],clabels=0,cbar=0,lwd=0.5,fsz=5") plt.ContourSimple(X, Y, Z1, false, 7, "linestyles=['--'], linewidths=[0.7], colors=['gray'], levels=[0]") plt.ContourSimple(X, Y, Z2, false, 7, "linestyles=['--'], linewidths=[0.7], colors=['gray'], levels=[0]") } opt.Multi_fcnErr = CTPerror1(θ1, a, b, c, d, e) default: chk.Panic("problem %d is not available", problem) } // initialise optimiser opt.Init(goga.GenTrialSolutions, nil, fcn, nf, ng, nh) // initial solutions var sols0 []*goga.Solution if false { sols0 = opt.GetSolutionsCopy() } // solve opt.RunMany("", "") goga.StatMulti(opt, true) io.PfYel("Tsys = %v\n", opt.SysTime) // check goga.CheckFront0(opt, true) // plot if true { feasibleOnly := false plt.SetForEps(0.8, 300) fmtAll := &plt.Fmt{L: "final solutions", M: ".", C: "orange", Ls: "none", Ms: 3} fmtFront := &plt.Fmt{L: "final Pareto front", C: "r", M: "o", Ms: 3, Ls: "none"} goga.PlotOvaOvaPareto(opt, sols0, 0, 1, feasibleOnly, fmtAll, fmtFront) extraplot() //plt.AxisYrange(0, f1max) if problem > 0 && problem < 6 { plt.Text(0.05, 0.05, "unfeasible", "color='gray', ha='left',va='bottom'") plt.Text(0.95, f1max-0.05, "feasible", "color='white', ha='right',va='top'") } if opt.RptName == "CTP6" { plt.Text(0.02, 0.15, "unfeasible", "rotation=-7,color='gray', ha='left',va='bottom'") plt.Text(0.02, 6.50, "unfeasible", "rotation=-7,color='gray', ha='left',va='bottom'") plt.Text(0.02, 13.0, "unfeasible", "rotation=-7,color='gray', ha='left',va='bottom'") plt.Text(0.50, 2.40, "feasible", "rotation=-7,color='white', ha='center',va='bottom'") plt.Text(0.50, 8.80, "feasible", "rotation=-7,color='white', ha='center',va='bottom'") plt.Text(0.50, 15.30, "feasible", "rotation=-7,color='white', ha='center',va='bottom'") } if opt.RptName == "TNK" { plt.Text(0.05, 0.05, "unfeasible", "color='gray', ha='left',va='bottom'") plt.Text(0.80, 0.85, "feasible", "color='white', ha='left',va='top'") plt.Equal() plt.AxisRange(0, 1.22, 0, 1.22) } plt.SaveD("/tmp/goga", io.Sf("%s.eps", opt.RptName)) } return }
// PlotOct plots a function cross-section and gradients projections on octahedral plane func PlotOct(filename string, σcCte, rmin, rmax float64, nr, nα int, φ float64, F Cb_F_t, G Cb_G_t, notpolarc, simplec, only0, grads, showpts, first, last bool, ferr float64, args ...interface{}) { A := make([]float64, 6) dfdA := make([]float64, 6) dα := 2.0 * math.Pi / float64(nα) dr := (rmax - rmin) / float64(nr-1) αmin := -math.Pi / 6.0 if notpolarc { rmin = -rmax dr = (rmax - rmin) / float64(nr-1) nα = nr dα = dr αmin = rmin } x, y, f := la.MatAlloc(nα, nr), la.MatAlloc(nα, nr), la.MatAlloc(nα, nr) //var gx, gy, L [][]float64 var gx, gy [][]float64 if grads { gx, gy = la.MatAlloc(nα, nr), la.MatAlloc(nα, nr) //L = O2Lmat() } var σa, σb []float64 if showpts { σa, σb = make([]float64, nα*nr), make([]float64, nα*nr) } k := 0 var err error for i := 0; i < nα; i++ { for j := 0; j < nr; j++ { α := αmin + float64(i)*dα r := rmin + float64(j)*dr if notpolarc { x[i][j] = α // σa y[i][j] = r // σb } else { x[i][j] = r * math.Cos(α) // σa y[i][j] = r * math.Sin(α) // σb } A[0], A[1], A[2] = O2L(x[i][j], y[i][j], σcCte) if showpts { σa[k] = x[i][j] σb[k] = y[i][j] } f[i][j], err = F(A, args...) if err != nil { if ferr > 0 { f[i][j] = ferr } else { chk.Panic(_octahedral_err1, "func", err) } } if grads { _, err = G(dfdA, A, args...) if err != nil { chk.Panic(_octahedral_err1, "grads", err) } /* gx[i][j] = -o.dfdλ[0]*L[0][0] - o.dfdλ[1]*L[1][0] - o.dfdλ[2]*L[2][0] gy[i][j] = -o.dfdλ[0]*L[0][1] - o.dfdλ[1]*L[1][1] - o.dfdλ[2]*L[2][1] */ } k += 1 } } if first { plt.Reset() plt.SetForPng(1, 500, 125) PlotRosette(1.1*rmax, true, true, true, 7) PlotRefOct(φ, σcCte, false) if showpts { plt.Plot(σa, σb, "'k.', ms=5") } } if simplec { if !only0 { plt.ContourSimple(x, y, f, false, 8, "") } plt.ContourSimple(x, y, f, false, 8, "levels=[0], colors=['blue'], linewidths=[2]") } else { plt.Contour(x, y, f, "fsz=8") } if grads { plt.Quiver(x, y, gx, gy, "") } if last { plt.AxisOff() plt.Equal() plt.SaveD("/tmp", filename) } }
// 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", ) } }