Ejemplo n.º 1
0
// PlotStar plots star with normalised OVAs
func (o *Optimiser) PlotStar() {
	nf := o.Nf
	dθ := 2.0 * math.Pi / float64(nf)
	θ0 := 0.0
	if nf == 3 {
		θ0 = -math.Pi / 6.0
	}
	for _, ρ := range []float64{0.25, 0.5, 0.75, 1.0} {
		plt.Circle(0, 0, ρ, "ec='gray',lw=0.5,zorder=5")
	}
	arrowM, textM := 1.1, 1.15
	for i := 0; i < nf; i++ {
		θ := θ0 + float64(i)*dθ
		xi, yi := 0.0, 0.0
		xf, yf := arrowM*math.Cos(θ), arrowM*math.Sin(θ)
		plt.Arrow(xi, yi, xf, yf, "sc=10,st='->',lw=0.7,zorder=10,clip_on=0")
		plt.PlotOne(xf, yf, "'k+', ms=0")
		xf, yf = textM*math.Cos(θ), textM*math.Sin(θ)
		plt.Text(xf, yf, io.Sf("%d", i), "size=6,zorder=10,clip_on=0")
	}
	X, Y := make([]float64, nf+1), make([]float64, nf+1)
	clr := false
	neg := false
	step := 1
	count := 0
	colors := []string{"m", "orange", "g", "r", "b", "k"}
	var ρ float64
	for i, sol := range o.Solutions {
		if sol.Feasible() && sol.FrontId == 0 && i%step == 0 {
			for j := 0; j < nf; j++ {
				if neg {
					ρ = 1.0 - sol.Ova[j]/(o.RptFmax[j]-o.RptFmin[j])
				} else {
					ρ = sol.Ova[j] / (o.RptFmax[j] - o.RptFmin[j])
				}
				θ := θ0 + float64(j)*dθ
				X[j], Y[j] = ρ*math.Cos(θ), ρ*math.Sin(θ)
			}
			X[nf], Y[nf] = X[0], Y[0]
			if clr {
				j := count % len(colors)
				plt.Plot(X, Y, io.Sf("'k-',color='%s',markersize=3,clip_on=0", colors[j]))
			} else {
				plt.Plot(X, Y, "'r-',marker='.',markersize=3,clip_on=0")
			}
			count++
		}
	}
	plt.Equal()
	plt.AxisOff()
}
Ejemplo n.º 2
0
func (o *Plotter) Plot_s3_s1(x, y []float64, res []*State, sts [][]float64, last bool) {
	// stress path
	nr := len(res)
	k := nr - 1
	x2 := make([]float64, nr)
	var xmi, xma, ymi, yma float64
	for i := 0; i < nr; i++ {
		σ1, σ2, σ3, err := tsr.M_PrincValsNum(res[i].Sig)
		if err != nil {
			chk.Panic("computation of eigenvalues failed", err)
		}
		x[i], y[i] = -tsr.SQ2*σ3, -σ1
		x2[i] = -tsr.SQ2 * σ2
		if i == 0 {
			xmi, xma = x[i], x[i]
			ymi, yma = y[i], y[i]
		} else {
			xmi = min(min(xmi, x[i]), x2[i])
			xma = max(max(xma, x[i]), x2[i])
			ymi = min(ymi, y[i])
			yma = max(yma, y[i])
		}
	}
	plt.Plot(x, y, io.Sf("'r.', ls='%s', clip_on=0, color='%s', marker='%s', label=r'$\\sigma_3$ %s'", o.Ls, o.Clr, o.Mrk, o.Lbl))
	plt.Plot(x2, y, io.Sf("'r.', ls='%s', clip_on=0, color='%s', marker='%s', label=r'$\\sigma_2$ %s'", o.LsAlt, o.Clr, o.Mrk, o.Lbl))
	plt.PlotOne(x[0], y[0], io.Sf("'bo', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.SpMrk, o.SpMs))
	plt.PlotOne(x[k], y[k], io.Sf("'bs', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.EpMrk, o.EpMs))
	// yield surface
	if o.WithYs && o.m != nil {
		if o.UsePmin {
			xmi = min(xmi, o.Pmin*tsr.SQ2)
			ymi = min(ymi, o.Pmin)
		}
		if o.UsePmax {
			xma = max(xma, o.Pmax*tsr.SQ2)
			yma = max(yma, o.Pmax)
		}
		xmi, xma, ymi, yma = o.fix_range(0, xmi, xma, ymi, yma)
		if o.S3s1Lims != nil {
			xmi, xma, ymi, yma = o.S3s1Lims[0], o.S3s1Lims[1], o.S3s1Lims[2], o.S3s1Lims[3]
		}
		//io.Pforan("xmi,xma ymi,yma = %v,%v %v,%v\n", xmi,xma, ymi,yma)
		dx := (xma - xmi) / float64(o.NptsSig-1)
		dy := (yma - ymi) / float64(o.NptsSig-1)
		xx := la.MatAlloc(o.NptsSig, o.NptsSig)
		yy := la.MatAlloc(o.NptsSig, o.NptsSig)
		zz := la.MatAlloc(o.NptsSig, o.NptsSig)
		v := NewState(len(res[0].Sig), len(res[0].Alp), false, len(res[0].EpsE) > 0)
		for k := 0; k < nr; k++ {
			copy(v.Alp, res[k].Alp)
			v.Dgam = res[k].Dgam
			for i := 0; i < o.NptsSig; i++ {
				for j := 0; j < o.NptsSig; j++ {
					xx[i][j] = xmi + float64(i)*dx
					yy[i][j] = ymi + float64(j)*dy
					v.Sig[0], v.Sig[1], v.Sig[2] = -yy[i][j], -xx[i][j]/tsr.SQ2, -xx[i][j]/tsr.SQ2
					ys := o.m.YieldFuncs(v)
					zz[i][j] = ys[0]
				}
			}
			plt.ContourSimple(xx, yy, zz, io.Sf("colors=['%s'], levels=[0], linestyles=['%s'], linewidths=[%g], clip_on=0", o.YsClr0, o.YsLs0, o.YsLw0)+o.ArgsYs)
		}
	}
	// predictor-corrector
	if len(o.PreCor) > 1 {
		var σ3, σ1, σ3new, σ1new float64
		for i := 1; i < len(o.PreCor); i++ {
			σ1, _, σ3, _ = tsr.M_PrincValsNum(o.PreCor[i-1])
			σ1new, _, σ3new, _ = tsr.M_PrincValsNum(o.PreCor[i])
			if math.Abs(σ3new-σ3) > 1e-7 || math.Abs(σ1new-σ1) > 1e-7 {
				plt.Arrow(-σ3*tsr.SQ2, -σ1, -σ3new*tsr.SQ2, -σ1new, io.Sf("sc=%d, fc='%s', ec='%s'", o.ArrWid, o.ClrPC, o.ClrPC))
			}
		}
	}
	// settings
	if last {
		plt.Equal()
		plt.Gll("$-\\sqrt{2}\\sigma_3$", "$-\\sigma_1$", "leg=1, leg_out=1, leg_ncol=4, leg_hlen=2")
		if lims, ok := o.Lims["s3,s1"]; ok {
			plt.AxisLims(lims)
		}
		if lims, ok := o.Lims["s3,s1,ys"]; ok {
			plt.AxisLims(lims)
		}
	}
}
Ejemplo n.º 3
0
func (o *Plotter) Plot_oct(x, y []float64, res []*State, sts [][]float64, last bool) {
	// stress path
	nr := len(res)
	k := nr - 1
	var σa, σb, xmi, xma, ymi, yma float64
	for i := 0; i < nr; i++ {
		σa, σb, _ = tsr.PQW2O(o.P[i], o.Q[i], o.W[i])
		x[i], y[i] = σa, σb
		o.maxR = max(o.maxR, math.Sqrt(σa*σa+σb*σb))
		if i == 0 {
			xmi, xma = x[i], x[i]
			ymi, yma = y[i], y[i]
		} else {
			xmi = min(xmi, x[i])
			xma = max(xma, x[i])
			ymi = min(ymi, y[i])
			yma = max(yma, y[i])
		}
	}
	plt.Plot(x, y, io.Sf("'r.', ls='%s', clip_on=0, color='%s', marker='%s', label=r'%s'", o.Ls, o.Clr, o.Mrk, o.Lbl))
	plt.PlotOne(x[0], y[0], io.Sf("'bo', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.SpMrk, o.SpMs))
	plt.PlotOne(x[k], y[k], io.Sf("'bs', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.EpMrk, o.EpMs))
	// fix range and max radius
	xmi, xma, ymi, yma = o.fix_range(0, xmi, xma, ymi, yma)
	rr := math.Sqrt((xma-xmi)*(xma-xmi) + (yma-ymi)*(yma-ymi))
	if o.maxR < rr {
		o.maxR = rr
	}
	if o.maxR < 1e-10 {
		o.maxR = 1
	}
	if yma > -xmi {
		xmi = -yma
	}
	if o.OctLims != nil {
		xmi, xma, ymi, yma = o.OctLims[0], o.OctLims[1], o.OctLims[2], o.OctLims[3]
	}
	//xmi, xma, ymi, yma = -20000, 20000, -20000, 20000
	// yield surface
	var σcmax float64
	if o.WithYs && o.m != nil {
		//io.Pforan("xmi,xma ymi,yma = %v,%v %v,%v\n", xmi,xma, ymi,yma)
		dx := (xma - xmi) / float64(o.NptsOct-1)
		dy := (yma - ymi) / float64(o.NptsOct-1)
		xx := la.MatAlloc(o.NptsOct, o.NptsOct)
		yy := la.MatAlloc(o.NptsOct, o.NptsOct)
		zz := la.MatAlloc(o.NptsOct, o.NptsOct)
		var λ0, λ1, λ2, σc float64
		v := NewState(len(res[0].Sig), len(res[0].Alp), false, len(res[0].EpsE) > 0)
		for k := 0; k < nr; k++ {
			copy(v.Alp, res[k].Alp)
			v.Dgam = res[k].Dgam
			σc = tsr.M_p(res[k].Sig) * tsr.SQ3
			//σc = 30000
			σcmax = max(σcmax, σc)
			for i := 0; i < o.NptsOct; i++ {
				for j := 0; j < o.NptsOct; j++ {
					xx[i][j] = xmi + float64(i)*dx
					yy[i][j] = ymi + float64(j)*dy
					λ0, λ1, λ2 = tsr.O2L(xx[i][j], yy[i][j], σc)
					v.Sig[0], v.Sig[1], v.Sig[2] = λ0, λ1, λ2
					ys := o.m.YieldFuncs(v)
					zz[i][j] = ys[0]
				}
			}
			plt.ContourSimple(xx, yy, zz, io.Sf("colors=['%s'], levels=[0], linestyles=['%s'], linewidths=[%g], clip_on=0", o.YsClr0, o.YsLs0, o.YsLw0)+o.ArgsYs)

		}
	}
	// predictor-corrector
	if len(o.PreCor) > 1 {
		var σa, σb, σanew, σbnew float64
		for i := 1; i < len(o.PreCor); i++ {
			σa, σb, _ = tsr.M_oct(o.PreCor[i-1])
			σanew, σbnew, _ = tsr.M_oct(o.PreCor[i])
			if math.Abs(σanew-σa) > 1e-7 || math.Abs(σbnew-σb) > 1e-7 {
				//plt.Plot([]float64{σa,σanew}, []float64{σb,σbnew}, "'k+', ms=3, color='k'")
				plt.Arrow(σa, σb, σanew, σbnew, io.Sf("sc=%d, fc='%s', ec='%s'", o.ArrWid, o.ClrPC, o.ClrPC))
			}
			o.maxR = max(o.maxR, math.Sqrt(σa*σa+σb*σb))
			o.maxR = max(o.maxR, math.Sqrt(σanew*σanew+σbnew*σbnew))
		}
	}
	// rosette and settings
	if last {
		tsr.PlotRefOct(o.Phi, σcmax, true)
		tsr.PlotRosette(o.maxR, false, true, true, 6)
		if o.OctAxOff {
			plt.AxisOff()
		}
		plt.Gll("$\\sigma_a$", "$\\sigma_b$", "")
		if lims, ok := o.Lims["oct"]; ok {
			plt.AxisLims(lims)
		}
		if lims, ok := o.Lims["oct,ys"]; ok {
			plt.AxisLims(lims)
		}
	}
}
Ejemplo n.º 4
0
func (o *Plotter) Plot_p_q(x, y []float64, res []*State, sts [][]float64, last bool) {
	// stress path
	nr := len(res)
	k := nr - 1
	var xmi, xma, ymi, yma float64
	for i := 0; i < nr; i++ {
		x[i], y[i] = o.P[i], o.Q[i]
		if o.Multq {
			mult := fun.Sign(o.W[i])
			y[i] *= mult
		}
		if o.UseOct {
			x[i] *= tsr.SQ3
			y[i] *= tsr.SQ2by3
		}
		if i == 0 {
			xmi, xma = x[i], x[i]
			ymi, yma = y[i], y[i]
		} else {
			xmi = min(xmi, x[i])
			xma = max(xma, x[i])
			ymi = min(ymi, y[i])
			yma = max(yma, y[i])
		}
		if o.SMPon {
			x[i], y[i], _ = tsr.M_pq_smp(res[i].Sig, o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
		}
	}
	plt.Plot(x, y, io.Sf("'r.', ls='%s', clip_on=0, color='%s', marker='%s', label=r'%s'", o.Ls, o.Clr, o.Mrk, o.Lbl))
	plt.PlotOne(x[0], y[0], io.Sf("'bo', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.SpMrk, o.SpMs))
	plt.PlotOne(x[k], y[k], io.Sf("'bs', clip_on=0, color='%s', marker='%s', ms=%d", o.SpClr, o.EpMrk, o.EpMs))
	// yield surface
	if o.WithYs && o.m != nil {
		mx, my := 1.0, 1.0
		if o.UseOct {
			mx, my = tsr.SQ3, tsr.SQ2by3
		}
		if o.UsePmin {
			xmi = min(xmi, o.Pmin*mx)
		}
		if o.UsePmax {
			xma = max(xma, o.Pmax*mx)
			yma = max(yma, o.Pmax*my)
		}
		xmi, xma, ymi, yma = o.fix_range(xmi, xmi, xma, ymi, yma)
		if o.PqLims != nil {
			xmi, xma, ymi, yma = o.PqLims[0], o.PqLims[1], o.PqLims[2], o.PqLims[3]
		}
		//io.Pforan("xmi,xma ymi,yma = %v,%v %v,%v\n", xmi,xma, ymi,yma)
		dx := (xma - xmi) / float64(o.NptsPq-1)
		dy := (yma - ymi) / float64(o.NptsPq-1)
		xx := la.MatAlloc(o.NptsPq, o.NptsPq)
		yy := la.MatAlloc(o.NptsPq, o.NptsPq)
		za := la.MatAlloc(o.NptsPq, o.NptsPq)
		zb := la.MatAlloc(o.NptsPq, o.NptsPq)
		var p, q, σa, σb, σc, λ0, λ1, λ2 float64
		v := NewState(len(res[0].Sig), len(res[0].Alp), false, len(res[0].EpsE) > 0)
		for k := 0; k < nr; k++ {
			copy(v.Alp, res[k].Alp)
			v.Dgam = res[k].Dgam
			for i := 0; i < o.NptsPq; i++ {
				for j := 0; j < o.NptsPq; j++ {
					xx[i][j] = xmi + float64(i)*dx
					yy[i][j] = ymi + float64(j)*dy
					p, q = xx[i][j], yy[i][j]
					if o.UseOct {
						p /= tsr.SQ3
						q /= tsr.SQ2by3
					}
					σa, σb, σc = tsr.PQW2O(p, q, o.W[k])
					λ0, λ1, λ2 = tsr.O2L(σa, σb, σc)
					v.Sig[0], v.Sig[1], v.Sig[2] = λ0, λ1, λ2
					ys := o.m.YieldFuncs(v)
					za[i][j] = ys[0]
					if o.nsurf > 1 {
						zb[i][j] = ys[1]
					}
					if o.SMPon {
						xx[i][j], yy[i][j], _ = tsr.M_pq_smp(v.Sig, o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
					}
				}
			}
			plt.ContourSimple(xx, yy, za, io.Sf("colors=['%s'], levels=[0], linestyles=['%s'], linewidths=[%g], clip_on=0", o.YsClr0, o.YsLs0, o.YsLw0)+o.ArgsYs)
			if o.nsurf > 1 {
				plt.ContourSimple(xx, yy, zb, io.Sf("colors=['%s'], levels=[0], linestyles=['%s'], linewidths=[%g], clip_on=0", o.YsClr1, o.YsLs1, o.YsLw1)+o.ArgsYs)
			}
		}
	}
	// predictor-corrector
	if len(o.PreCor) > 1 {
		var p, q, pnew, qnew float64
		for i := 1; i < len(o.PreCor); i++ {
			p = tsr.M_p(o.PreCor[i-1])
			q = tsr.M_q(o.PreCor[i-1])
			pnew = tsr.M_p(o.PreCor[i])
			qnew = tsr.M_q(o.PreCor[i])
			if o.UseOct {
				p *= tsr.SQ3
				pnew *= tsr.SQ3
				q *= tsr.SQ2by3
				qnew *= tsr.SQ2by3
			}
			if o.SMPon {
				p, q, _ = tsr.M_pq_smp(o.PreCor[i-1], o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
				pnew, qnew, _ = tsr.M_pq_smp(o.PreCor[i], o.SMPa, o.SMPb, o.SMPβ, o.SMPϵ)
			}
			if math.Abs(pnew-p) > 1e-10 || math.Abs(qnew-q) > 1e-10 {
				plt.Arrow(p, q, pnew, qnew, io.Sf("sc=%d, fc='%s', ec='%s'", o.ArrWid, o.ClrPC, o.ClrPC))
			}
		}
	}
	// settings
	if last {
		plt.Equal()
		xl, yl := "$p_{cam}$", "$q_{cam}$"
		if o.UseOct {
			xl, yl = "$p_{oct}$", "$q_{oct}$"
		}
		if o.SMPon {
			xl, yl = "$p_{smp}$", "$q_{smp}$"
		}
		if o.AxLblX != "" {
			xl = o.AxLblX
		}
		if o.AxLblY != "" {
			yl = o.AxLblY
		}
		plt.Gll(xl, yl, "leg_out=1, leg_ncol=4, leg_hlen=1.5")
		if lims, ok := o.Lims["p,q"]; ok {
			plt.AxisLims(lims)
		}
		if lims, ok := o.Lims["p,q,ys"]; ok {
			plt.AxisLims(lims)
		}
	}
}
Ejemplo n.º 5
0
// Draw draws grid
//  r   -- radius of circles
//  W   -- width of paths
//  dwt -- δwt for positioning text (w = W/2)
//  arrow_scale -- scale for arrows. use 0 for default value
func (o *Graph) Draw(dirout, fname string, r, W, dwt, arrow_scale float64,
	verts_lbls map[int]string, verts_fsz float64, verts_clr string,
	edges_lbls map[int]string, edges_fsz float64, edges_clr string) {
	if len(o.Verts) < 1 {
		return
	}
	xmin, ymin := o.Verts[0][0], o.Verts[0][1]
	xmax, ymax := xmin, ymin
	var lbl string
	for i, v := range o.Verts {
		if verts_lbls == nil {
			lbl = io.Sf("%d", i)
		} else {
			lbl = verts_lbls[i]
		}
		plt.Text(v[0], v[1], lbl, io.Sf("clip_on=0, color='%s', fontsize=%g, ha='center', va='center'", verts_clr, verts_fsz))
		plt.Circle(v[0], v[1], r, "clip_on=0, ec='k', lw=0.8")
		xmin, ymin = utl.Min(xmin, v[0]), utl.Min(ymin, v[1])
		xmax, ymax = utl.Max(xmax, v[0]), utl.Max(ymax, v[1])
	}
	if W > 2*r {
		W = 1.8 * r
	}
	w := W / 2.0
	xa, xb := make([]float64, 2), make([]float64, 2)
	xc, dx := make([]float64, 2), make([]float64, 2)
	mu, nu := make([]float64, 2), make([]float64, 2)
	xi, xj := make([]float64, 2), make([]float64, 2)
	l := math.Sqrt(r*r - w*w)
	var L float64
	if arrow_scale <= 0 {
		arrow_scale = 20
	}
	for k, e := range o.Edges {
		L = 0.0
		for i := 0; i < 2; i++ {
			xa[i] = o.Verts[e[0]][i]
			xb[i] = o.Verts[e[1]][i]
			xc[i] = (xa[i] + xb[i]) / 2.0
			dx[i] = xb[i] - xa[i]
			L += dx[i] * dx[i]
		}
		L = math.Sqrt(L)
		mu[0], mu[1] = dx[0]/L, dx[1]/L
		nu[0], nu[1] = -dx[1]/L, dx[0]/L
		for i := 0; i < 2; i++ {
			xi[i] = xa[i] + l*mu[i] - w*nu[i]
			xj[i] = xb[i] - l*mu[i] - w*nu[i]
			xc[i] = (xi[i]+xj[i])/2.0 - dwt*nu[i]
		}
		plt.Arrow(xi[0], xi[1], xj[0], xj[1], io.Sf("st='->', sc=%g", arrow_scale))
		if edges_lbls == nil {
			lbl = io.Sf("%d", k)
		} else {
			lbl = edges_lbls[k]
		}
		plt.Text(xc[0], xc[1], lbl, io.Sf("clip_on=0, color='%s', fontsize=%g, ha='center', va='center'", edges_clr, edges_fsz))
	}
	xmin -= r
	xmax += r
	ymin -= r
	ymax += r
	plt.AxisOff()
	plt.Equal()
	plt.AxisRange(xmin, xmax, ymin, ymax)
	plt.SaveD(dirout, fname)
}
Ejemplo n.º 6
0
// DistPoint returns the distance from a point to this Bezier curve
// It finds the closest projection which is stored in P
func (o *BezierQuad) DistPoint(X []float64, doplot bool) float64 {

	// TODO:
	//   1) split this into closest projections finding
	//   2) finish distance computation

	// check
	if len(o.Q) != 3 {
		chk.Panic("DistPoint: quadratic Bezier must be initialised first (with 3 control points)")
	}
	ndim := len(o.Q[0])
	chk.IntAssert(len(X), ndim)

	// solve cubic equation
	var A_i, B_i, M_i, a, b, c, d float64
	for i := 0; i < ndim; i++ {
		A_i = o.Q[2][i] - 2.0*o.Q[1][i] + o.Q[0][i]
		B_i = o.Q[1][i] - o.Q[0][i]
		M_i = o.Q[0][i] - X[i]
		a += A_i * A_i
		b += 3.0 * A_i * B_i
		c += 2.0*B_i*B_i + M_i*A_i
		d += M_i * B_i
	}
	//io.Pforan("a=%v b=%v c=%v d=%v\n", a, b, c, d)
	if math.Abs(a) < 1e-7 {
		chk.Panic("DistPoint does not yet work with this type of Bezier (straight line?):\nQ=%v\n", o.Q)
	}
	x1, x2, x3, nx := num.EqCubicSolveReal(b/a, c/a, d/a)
	io.Pfyel("\nx1=%v x2=%v x3=%v nx=%v\n", x1, x2, x3, nx)

	// auxiliary
	if len(o.P) != ndim {
		o.P = make([]float64, ndim)
	}

	// closest projections
	t := x1
	if nx == 2 {
		chk.Panic("nx=2 => not implemented yet")
	}
	if nx == 3 {
		T := []float64{x1, x2, x3}
		D := []float64{-1, -1, -1}
		ok := []bool{
			!(x1 < 0.0 || x1 > 1.0),
			!(x2 < 0.0 || x2 > 1.0),
			!(x3 < 0.0 || x3 > 1.0),
		}
		io.Pforan("ok = %v\n", ok)
		for i, t := range T {
			if ok[i] {
				o.Point(o.P, t)
				if doplot {
					plt.PlotOne(X[0], X[1], "'ko'")
					plt.PlotOne(o.P[0], o.P[1], "'k.'")
					plt.Arrow(X[0], X[1], o.P[0], o.P[1], "ec='none'")
				}
				D[i] = ppdist(X, o.P)
			}
		}
		io.Pforan("D = %v\n", D)
	}
	o.Point(o.P, t)
	io.Pfcyan("P = %v\n", o.P)
	return 0
}
Ejemplo n.º 7
0
func main() {

	PI := math.Pi

	yf := func(x float64) float64 {
		return 1.0 - math.Sqrt(x) - math.Sin(10.0*math.Pi*x)*x
	}

	dydx := func(x float64) float64 {
		return -math.Sin(10.0*PI*x) - 10.0*PI*x*math.Cos(10.0*PI*x) - 1.0/(2.0*math.Sqrt(x))
	}

	var nlsDY num.NlSolver
	nlsDY.Init(1, func(fx, x []float64) error {
		fx[0] = dydx(x[0])
		return nil
	}, nil, nil, false, true, nil)
	defer nlsDY.Clean()

	X := []float64{0.09, 0.25, 0.45, 0.65, 0.85}
	Y := make([]float64, len(X))
	for i, x := range X {

		// find min
		xx := []float64{x}
		err := nlsDY.Solve(xx, true)
		if err != nil {
			io.PfRed("dydx nls failed:\n%v", err)
			return
		}
		X[i] = xx[0]
		Y[i] = yf(X[i])
	}

	// find next point along horizontal line
	Xnext := []float64{0.2, 0.4, 0.6, 0.8}
	Ynext := make([]float64, len(Xnext))
	for i, xnext := range Xnext {
		var nlsX num.NlSolver
		nlsX.Init(1, func(fx, x []float64) error {
			fx[0] = Y[i] - yf(x[0])
			return nil
		}, nil, nil, false, true, nil)
		defer nlsX.Clean()
		xx := []float64{xnext}
		err := nlsX.Solve(xx, true)
		if err != nil {
			io.PfRed("dydx nls failed:\n%v", err)
			return
		}
		Xnext[i] = xx[0]
		Ynext[i] = yf(Xnext[i])
	}

	// auxiliary points
	XX := []float64{
		0, X[0],
		Xnext[0], X[1],
		Xnext[1], X[2],
		Xnext[2], X[3],
		Xnext[3], X[4],
	}
	YY := []float64{
		1, Y[0],
		Ynext[0], Y[1],
		Ynext[1], Y[2],
		Ynext[2], Y[3],
		Ynext[3], Y[4],
	}
	io.Pforan("XX = %.3f\n", XX)
	io.Pforan("YY = %.3f\n", YY)

	// find arc-length
	arclen := 0.0
	for i := 0; i < len(XX); i += 2 {
		a := XX[i]
		b := XX[i+1]
		if i == 0 {
			a += 1e-7
		}
		var quad num.Simp
		quad.Init(func(x float64) float64 {
			return math.Sqrt(1.0 + math.Pow(dydx(x), 2.0))
		}, a, b, 1e-4)
		res, err := quad.Integrate()
		if err != nil {
			io.PfRed("quad failed:\n%v", err)
			return
		}
		arclen += res
		io.Pf("int(...) from %.15f to %.15f = %g\n", a, b, res)
	}
	io.Pforan("arclen = %v\n", arclen)

	np := 201
	xx := utl.LinSpace(0, 1, np)
	yy := make([]float64, np)
	for i := 0; i < np; i++ {
		yy[i] = yf(xx[i])
	}
	plt.Plot(xx, yy, "'b-', clip_on=0")
	for i, x := range X {
		plt.PlotOne(x, Y[i], "'r|', mew=2, ms=30, clip_on=0")
	}
	for i, x := range Xnext {
		plt.PlotOne(x, Ynext[i], "'r_', mew=2, ms=30, clip_on=0")
	}
	for i := 0; i < len(XX); i += 2 {
		x0, y0 := XX[i], YY[i]
		x1, y1 := XX[i+1], YY[i+1]
		plt.Arrow(x0, y0, x1, y1, "")
	}
	plt.SetXnticks(11)
	plt.Gll("x", "y", "")
	plt.SaveD("/tmp/goga", "calcZDT3pts.eps")
}