Esempio n. 1
0
func PrintIndicatorMatrix(x [][]int) (l string) {
	m, n := len(x), len(x[0])
	w := 2*n + 6 + 13
	l = io.Sf("%s i\\j |", io.StrThickLine(w))
	for j := 0; j < n; j++ {
		l += io.Sf("%2d", j)
	}
	l += io.Sf(" |        sum\n%s", io.StrThinLine(w))
	S := make([]int, n)
	for i := 0; i < m; i++ {
		l += io.Sf(" %3d |", i)
		s := 0
		for j := 0; j < n; j++ {
			l += io.Sf("%2d", x[i][j])
			s += x[i][j]
			S[j] += x[i][j]
		}
		l += io.Sf(" | Σ xij = %2d\n", s)
	}
	l += io.Sf("%s sum =", io.StrThinLine(w))
	for j := 0; j < n; j++ {
		l += io.Sf("%2d", S[j])
	}
	l += io.Sf("\n%s", io.StrThickLine(w))
	return
}
Esempio n. 2
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
}
Esempio n. 3
0
// Output generates a nice table with population data
func (o Population) Output(C *ConfParams) (buf *bytes.Buffer) {

	// check
	if len(o) < 1 {
		return
	}

	// compute sizes and generate formats list
	if C.NumFmts == nil {
		sizes := make([][]int, 6)
		for _, ind := range o {
			sz := ind.GetStringSizes()
			for i := 0; i < 6; i++ {
				if len(sizes[i]) == 0 {
					sizes[i] = make([]int, len(sz[i]))
				}
				for j, s := range sz[i] {
					sizes[i][j] = utl.Imax(sizes[i][j], s)
				}
			}
		}
		name := []string{"int", "flt", "str", "key", "byt", "fun"}
		C.NumFmts = make(map[string][]string)
		for i, str := range []string{"d", "g", "s", "x", "s", "s"} {
			C.NumFmts[name[i]] = make([]string, len(sizes[i]))
			for j, sz := range sizes[i] {
				C.NumFmts[name[i]][j] = io.Sf("%%%d%s", sz+1, str)
			}
		}
	}

	// compute sizes of header items
	nova := len(o[0].Ovas)
	noor := len(o[0].Oors)
	szova, szoor, szdem := make([]int, nova), make([]int, noor), 0
	for k, ind := range o {
		if C.ShowNinds > 0 && k >= C.ShowNinds {
			break
		}
		for i := 0; i < nova; i++ {
			szova[i] = utl.Imax(szova[i], len(io.Sf("%g", ind.Ovas[i])))
		}
		if C.ShowOor {
			for i := 0; i < noor; i++ {
				szoor[i] = utl.Imax(szoor[i], len(io.Sf("%g", ind.Oors[i])))
			}
		}
		szdem = utl.Imax(szdem, len(io.Sf("%g", ind.Demerit)))
	}
	for i := 0; i < nova; i++ {
		szova[i] = utl.Imax(szova[i], 5) // 5 ==> len("Ova##")
	}
	if C.ShowOor {
		for i := 0; i < noor; i++ {
			szoor[i] = utl.Imax(szoor[i], 5) // 5 ==> len("Oor####")
		}
	}
	szdem = utl.Imax(szdem, 7) // 7 ==> len("Demerit")

	// print individuals
	fmtova := make([]string, nova)
	fmtoor := make([]string, noor)
	for i := 0; i < nova; i++ {
		fmtova[i] = io.Sf("%%%d", szova[i]+1)
	}
	if C.ShowOor {
		for i := 0; i < noor; i++ {
			fmtoor[i] = io.Sf("%%%d", szoor[i]+1)
		}
	}
	fmtdem := io.Sf("%%%d", szdem+1)
	line, sza, szb := "", 0, 0
	first := true
	for i, ind := range o {
		if C.ShowNinds > 0 && i >= C.ShowNinds {
			break
		}
		stra := ""
		for j := 0; j < nova; j++ {
			stra += io.Sf(fmtova[j]+"g", ind.Ovas[j])
		}
		if C.ShowOor {
			for j := 0; j < noor; j++ {
				if ind.Oors[j] > 0 {
					stra += io.Sf(fmtoor[j]+"g", ind.Oors[j])
				} else {
					stra += io.Sf(fmtoor[j]+"s", "n/a")
				}
			}
		} else {
			unfeasible := false
			for j := 0; j < noor; j++ {
				if ind.Oors[j] > 0 {
					unfeasible = true
				}
			}
			if unfeasible {
				stra += " unfe."
			} else {
				stra += "      "
			}
		}
		if C.ShowDem {
			stra += io.Sf(fmtdem+"g", ind.Demerit) + " "
		}
		strb := ind.Output(C.NumFmts, C.ShowBases)
		line += stra + strb + "\n"
		if first {
			sza, szb = len(stra), len(strb)
			first = false
		}
	}

	// write to buffer
	fmtgenes := io.Sf("%%%d.%ds\n", szb, szb)
	n := sza + szb
	buf = new(bytes.Buffer)
	io.Ff(buf, io.StrThickLine(n))
	for i := 0; i < nova; i++ {
		io.Ff(buf, fmtova[i]+"s", io.Sf("Ova%d", i))
	}
	if C.ShowOor {
		for i := 0; i < noor; i++ {
			io.Ff(buf, fmtoor[i]+"s", io.Sf("Oor%d", i))
		}
	} else {
		io.Ff(buf, " check")
	}
	if C.ShowDem {
		io.Ff(buf, fmtdem+"s ", "Demerit")
	}
	io.Ff(buf, fmtgenes, "Genes")
	io.Ff(buf, io.StrThinLine(n))
	io.Ff(buf, line)
	io.Ff(buf, io.StrThickLine(n))
	return
}