// Init initialises simple flot problem structure func NewSimpleFltProb(fcn SimpleFltFcn_t, nf, ng, nh int, C *ConfParams) (o *SimpleFltProb) { // data o = new(SimpleFltProb) o.Fcn = fcn o.C = C o.C.Nova = nf o.C.Noor = ng + nh // sandbox o.nf, o.ng, o.nh = nf, ng, nh o.ff = utl.DblsAlloc(o.C.Nisl, o.nf) o.gg = utl.DblsAlloc(o.C.Nisl, o.ng) o.hh = utl.DblsAlloc(o.C.Nisl, o.nh) // objective function o.C.OvaOor = func(ind *Individual, isl, time int, report *bytes.Buffer) { x := ind.GetFloats() o.Fcn(o.ff[isl], o.gg[isl], o.hh[isl], x) for i, f := range o.ff[isl] { ind.Ovas[i] = f } for i, g := range o.gg[isl] { ind.Oors[i] = utl.GtePenalty(g, 0.0, 1) // g[i] ≥ 0 } for i, h := range o.hh[isl] { h = math.Abs(h) ind.Ovas[0] += h ind.Oors[ng+i] = utl.GtePenalty(o.C.Eps1, h, 1) // ϵ ≥ |h[i]| } } // evolver o.Evo = NewEvolver(o.C) // auxiliary o.NumfmtX = "%8.5f" o.NumfmtF = "%8.5f" // results and stat nx := len(o.C.RangeFlt) o.Xbest = utl.DblsAlloc(o.C.Ntrials, nx) // plotting if o.C.DoPlot { o.PopsIni = o.Evo.GetPopulations() o.PltDirout = "/tmp/goga" o.PltNpts = 41 o.PltLwg = 1.5 o.PltLwh = 1.5 } return }
// HaltonPoints generates randomly spaced points // x -- [dim][n] points func HaltonPoints(dim, n int) (x [][]float64) { x = utl.DblsAlloc(dim, n) for j := 0; j < dim; j++ { for i := 0; i < n; i++ { x[j][i] = halton(i, j) } } return }
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]") } }
// GetResults returns all ovas and oors // Output: // ova -- [nsol][nova] objective values // oor -- [nsol][noor] out-of-range values func GetResults(sols []*Solution, ovaOnly bool) (ova, oor [][]float64) { nsol := len(sols) nova := len(sols[0].Ova) noor := len(sols[0].Oor) ova = utl.DblsAlloc(nsol, nova) if !ovaOnly { oor = utl.DblsAlloc(nsol, noor) } for i, sol := range sols { for j := 0; j < nova; j++ { ova[i][j] = sol.Ova[j] } if !ovaOnly { for j := 0; j < noor; j++ { oor[i][j] = sol.Oor[j] } } } return }
func get_nurbs_xmat(nurbs *gm.Nurbs, ibasis []int) (xmat [][]float64) { nd := nurbs.Gnd() xmat = utl.DblsAlloc(nd, len(ibasis)) for k, l := range ibasis { q := nurbs.GetQl(l) for j := 0; j < nd; j++ { xmat[j][k] = q[j] } } return }
// Plot plot results func Plot(dirout, fn string, res *Results, yfcn Cb_ycorr, xa, xb float64, argsAna, argsNum string, extra func()) { // data if res == nil { return } ndim := len(res.Y) if ndim < 1 { return } // closed-form solution var xc []float64 var Yc [][]float64 if yfcn != nil { np := 101 dx := (xb - xa) / float64(np-1) xc = make([]float64, np) Yc = utl.DblsAlloc(np, ndim) for i := 0; i < np; i++ { xc[i] = xa + dx*float64(i) yfcn(Yc[i], xc[i]) } } // plot if argsAna == "" { argsAna = "'y-', lw=6, label='analytical', clip_on=0" } if argsNum == "" { argsNum = "'b-', marker='.', lw=1, clip_on=0" } for j := 0; j < ndim; j++ { plt.Subplot(ndim+1, 1, j+1) if yfcn != nil { plt.Plot(xc, Yc[j], argsAna) } plt.Plot(res.X, res.Y[j], argsNum+","+io.Sf("label='%s'", res.Method)) plt.Gll("$x$", "$y$", "") } plt.Subplot(ndim+1, 1, ndim+1) plt.Plot(res.X, res.Dx, io.Sf("'b-', marker='.', lw=1, clip_on=0, label='%s'", res.Method)) plt.SetYlog() plt.Gll("$x$", "$\\log(\\delta x)$", "") // write file if extra != nil { extra() } plt.SaveD(dirout, fn) }
// checkShape checks that shape functions result in 1.0 @ nodes func checkShape(tst *testing.T, shape string, tol float64, verbose bool) { // information fcn := Functions[shape] ndim := GeomNdim[shape] nverts := NumVerts[shape] coords := NatCoords[shape] // allocate slices S := make([]float64, nverts) dSdR := utl.DblsAlloc(nverts, ndim) // loop over all vertices errS := 0.0 r := []float64{0, 0, 0} for n := 0; n < nverts; n++ { // natural coordinates @ vertex for i := 0; i < ndim; i++ { r[i] = coords[i][n] } // compute function fcn(S, dSdR, r, false) // check if verbose { for _, val := range S { if math.Abs(val) < 1e-15 { val = 0 } io.Pf("%3v", val) } io.Pf("\n") } for m := 0; m < nverts; m++ { if n == m { errS += math.Abs(S[m] - 1.0) } else { errS += math.Abs(S[m]) } } } // error if errS > tol { tst.Errorf("%s failed with err = %g\n", shape, errS) return } }
// SimpleOutput implements a simple output function func SimpleOutput(first bool, dx, x float64, y []float64, args ...interface{}) (err error) { chk.IntAssert(len(args), 1) res := args[0].(*Results) res.Dx = append(res.Dx, dx) res.X = append(res.X, x) ndim := len(y) if len(res.Y) == 0 { res.Y = utl.DblsAlloc(ndim, 0) } for j := 0; j < ndim; j++ { res.Y[j] = append(res.Y[j], y[j]) } return }
// Init initialises Munkres' structure func (o *Munkres) Init(nrow, ncol int) { chk.IntAssertLessThan(0, nrow) // nrow > 1 chk.IntAssertLessThan(0, ncol) // ncol > 1 o.nrow, o.ncol = nrow, ncol o.C = utl.DblsAlloc(o.nrow, o.ncol) o.M = make([][]Mask_t, o.nrow) for i := 0; i < o.nrow; i++ { o.M[i] = make([]Mask_t, o.ncol) } o.Links = make([]int, o.nrow) npath := 2*o.nrow + 1 // TODO: check this o.path = utl.IntsAlloc(npath, 2) o.row_covered = make([]bool, o.nrow) o.col_covered = make([]bool, o.ncol) }
// Init initialises graph // Input: // edges -- [nedges][2] edges (connectivity) // weightsE -- [nedges] weights of edges. can be <nil> // verts -- [nverts][ndim] vertices. can be <nil> // weightsV -- [nverts] weights of vertices. can be <nil> func (o *Graph) Init(edges [][]int, weightsE []float64, verts [][]float64, weightsV []float64) { o.Edges, o.WeightsE = edges, weightsE o.Verts, o.WeightsV = verts, weightsV o.Shares = make(map[int][]int) o.Key2edge = make(map[int]int) for k, edge := range o.Edges { i, j := edge[0], edge[1] utl.IntIntsMapAppend(&o.Shares, i, k) utl.IntIntsMapAppend(&o.Shares, j, k) o.Key2edge[o.HashEdgeKey(i, j)] = k } if o.Verts != nil { chk.IntAssert(len(o.Verts), len(o.Shares)) } nv := len(o.Shares) o.Dist = utl.DblsAlloc(nv, nv) o.Next = utl.IntsAlloc(nv, nv) }
// PlotHc2d plots 2D hypercube func PlotHc2d(dirout, fnkey string, x [][]int, xrange [][]float64) { m := len(x) n := len(x[0]) dx := make([]float64, m) for i := 0; i < m; i++ { dx[i] = (xrange[i][1] - xrange[i][0]) / float64(n-1) } X := utl.DblsAlloc(m, n) for i := 0; i < m; i++ { for j := 0; j < n; j++ { X[i][j] = xrange[i][0] + float64(x[i][j]-1)*dx[i] } } plt.SetForEps(0.8, 300) plt.Plot(X[0], X[1], "'r.', clip_on=0, zorder=10") plt.Equal() plt.Gll("$x$", "$y$", "") plt.SaveD(dirout, fnkey+".eps") }
// Delaunay computes 2D Delaunay triangulation using Triangle // Input: // X = { x0, x1, x2, ... Npoints } // Y = { y0, y1, y2, ... Npoints } // Ouptut: // V = { { x0, y0 }, { x0, y0 }, { x0, y0 } ... Nvertices } // C = { { id0, id1, id2 }, { id0, id1, id2 } ... Ncellls } func Delaunay(X, Y []float64, verbose bool) (V [][]float64, C [][]int, err error) { // input chk.IntAssert(len(X), len(Y)) n := len(X) verb := 0 if verbose { verb = 1 } // perform triangulation var T C.triangulateio defer func() { C.trifree(&T) }() res := C.delaunay2d( &T, (C.long)(n), (*C.double)(unsafe.Pointer(&X[0])), (*C.double)(unsafe.Pointer(&Y[0])), (C.long)(verb), ) if res != 0 { chk.Err("Delaunay2d failed: Triangle returned %d code\n", res) } // output nverts := int(T.numberofpoints) ncells := int(T.numberoftriangles) V = utl.DblsAlloc(nverts, 2) C = utl.IntsAlloc(ncells, 3) for i := 0; i < nverts; i++ { V[i][0] = float64(C.getpoint((C.long)(i), 0, &T)) V[i][1] = float64(C.getpoint((C.long)(i), 1, &T)) } for i := 0; i < ncells; i++ { C[i][0] = int(C.getcorner((C.long)(i), 0, &T)) C[i][1] = int(C.getcorner((C.long)(i), 1, &T)) C[i][2] = int(C.getcorner((C.long)(i), 2, &T)) } return }
// checkDerivs checks dSdR derivatives of shape structures func checkDerivs(tst *testing.T, shape string, r []float64, tol float64, verbose bool) { // information fcn := Functions[shape] ndim := GeomNdim[shape] nverts := NumVerts[shape] // allocate slices S := make([]float64, nverts) dSdR := utl.DblsAlloc(nverts, ndim) // auxiliary r_tmp := make([]float64, len(r)) S_tmp := make([]float64, nverts) // analytical fcn(S, dSdR, r, true) // numerical for n := 0; n < nverts; n++ { for i := 0; i < ndim; i++ { dSndRi, _ := num.DerivCentral(func(t float64, args ...interface{}) (Sn float64) { copy(r_tmp, r) r_tmp[i] = t fcn(S_tmp, nil, r_tmp, false) Sn = S_tmp[n] return }, r[i], 1e-1) if verbose { io.Pfgrey2(" dS%ddR%d @ %5.2f = %v (num: %v)\n", n, i, r, dSdR[n][i], dSndRi) } if math.Abs(dSdR[n][i]-dSndRi) > tol { tst.Errorf("nurbs dS%ddR%d failed with err = %g\n", n, i, math.Abs(dSdR[n][i]-dSndRi)) return } } } }
// PlotHc3d plots 3D hypercube func PlotHc3d(dirout, fnkey string, x [][]int, xrange [][]float64, show bool) { m := len(x) n := len(x[0]) dx := make([]float64, m) for i := 0; i < m; i++ { dx[i] = (xrange[i][1] - xrange[i][0]) / float64(n-1) } X := utl.DblsAlloc(m, n) for i := 0; i < m; i++ { for j := 0; j < n; j++ { X[i][j] = xrange[i][0] + float64(x[i][j]-1)*dx[i] } } if !show { plt.SetForEps(0.8, 455) } plt.Plot3dPoints(X[0], X[1], X[2], "clip_on=0, zorder=10") if show { plt.Show() } else { plt.SaveD(dirout, fnkey+".eps") } }
// 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 test_rwstep01(tst *testing.T) { verbose() chk.PrintTitle("rwstep01") buf, err := io.ReadFile("rw/data/beadpanel.step") if err != nil { tst.Errorf("cannot read file:\n%v", err) return } dat := string(buf) var stp rw.STEP err = stp.ParseDATA(dat) if err != nil { tst.Errorf("Parse filed:\n%v", err) return } var bsplines []*Bspline for _, scurve := range stp.Scurves { curve := stp.BScurves[scurve.Curve_3d] if curve == nil { continue } // collect vertices nv := len(curve.Control_points_list) verts := utl.DblsAlloc(nv, 4) for i, key := range curve.Control_points_list { if p, ok := stp.Points[key]; ok { for j := 0; j < 3; j++ { verts[i][j] = p.Coordinates[j] } verts[i][3] = 1.0 } else { chk.Panic("cannot find point %q", key) } } // collect knots nk := 0 for _, m := range curve.Knot_multiplicities { nk += m } knots := make([]float64, nk) k := 0 for i, u := range curve.Knots { m := curve.Knot_multiplicities[i] for j := 0; j < m; j++ { knots[k] = u k++ } } // create B-spline bsp := new(Bspline) bsp.Init(knots, curve.Degree) bsp.SetControl(verts) bsplines = append(bsplines, bsp) } if true { io.Pforan("n = %v\n", len(bsplines)) for i, bsp := range bsplines { bsp.Draw3d("", "", 21, i == 0) } //plt.Show() } }
// 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", ) } }
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 }
// PlotDiagMoment plots bending moment diagram // Input: // M -- moment along stations // withtext -- show bending moment values // numfmt -- number format for values. use "" to chose default one // tolM -- tolerance to clip absolute values of M // sf -- scaling factor func (o *Beam) PlotDiagMoment(M []float64, withtext bool, numfmt string, tolM, sf float64) { // number of stations nstations := len(M) ds := 1.0 / float64(nstations-1) // nodes var xa, xb []float64 var u []float64 // out-of-pane vector if o.Ndim == 2 { xa = []float64{o.X[0][0], o.X[1][0], 0} xb = []float64{o.X[0][1], o.X[1][1], 0} u = []float64{0, 0, 1} } else { chk.Panic("TODO: 3D beam diagram") } // unit vector along beam v := make([]float64, 3) sum := 0.0 for j := 0; j < o.Ndim; j++ { v[j] = xb[j] - xa[j] sum += v[j] * v[j] } sum = math.Sqrt(sum) for j := 0; j < o.Ndim; j++ { v[j] /= sum } // unit normal n := make([]float64, 3) // normal utl.CrossProduct3d(n, u, v) // n := u cross v // auxiliary vectors x := make([]float64, o.Ndim) // station m := make([]float64, o.Ndim) // vector pointing to other side c := make([]float64, o.Ndim) // centre imin, imax := utl.DblArgMinMax(M) // draw text function draw_text := func(mom float64) { if math.Abs(mom) > tolM { α := math.Atan2(-n[1], -n[0]) * 180.0 / math.Pi str := io.Sf("%g", mom) if numfmt != "" { str = io.Sf(numfmt, mom) } else { if len(str) > 10 { str = io.Sf("%.10f", mom) // truncate number str = io.Sf("%g", io.Atof(str)) } } plt.Text(c[0], c[1], str, io.Sf("ha='center', size=7, rotation=%g, clip_on=0", α)) } } // draw pts := utl.DblsAlloc(nstations, 2) xx, yy := make([]float64, 2), make([]float64, 2) for i := 0; i < nstations; i++ { // station s := float64(i) * ds for j := 0; j < o.Ndim; j++ { x[j] = (1.0-s)*o.X[j][0] + s*o.X[j][1] } // auxiliary vectors for j := 0; j < o.Ndim; j++ { m[j] = x[j] - sf*M[i]*n[j] c[j] = (x[j] + m[j]) / 2.0 } // points on diagram pts[i][0], pts[i][1] = m[0], m[1] xx[0], xx[1] = x[0], m[0] yy[0], yy[1] = x[1], m[1] // draw clr, lw := "#919191", 1.0 if i == imin || i == imax { lw = 2 if M[i] < 0 { clr = "#9f0000" } else { clr = "#109f24" } } plt.Plot(xx, yy, io.Sf("'-', color='%s', lw=%g, clip_on=0", clr, lw)) if withtext { if i == imin || i == imax { // draw text @ min/max draw_text(M[i]) } else { if i == 0 || i == nstations-1 { // draw text @ extremities draw_text(M[i]) } } } } // draw polyline plt.DrawPolyline(pts, &plt.Sty{Ec: "k", Fc: "none", Lw: 1}, "") }