Beispiel #1
0
func main() {

	// input matrix in Triplet format
	// including repeated positions. e.g. (0,0)
	var A la.Triplet
	A.Init(5, 5, 13)
	A.Put(0, 0, 1.0) // << repeated
	A.Put(0, 0, 1.0) // << repeated
	A.Put(1, 0, 3.0)
	A.Put(0, 1, 3.0)
	A.Put(2, 1, -1.0)
	A.Put(4, 1, 4.0)
	A.Put(1, 2, 4.0)
	A.Put(2, 2, -3.0)
	A.Put(3, 2, 1.0)
	A.Put(4, 2, 2.0)
	A.Put(2, 3, 2.0)
	A.Put(1, 4, 6.0)
	A.Put(4, 4, 1.0)

	// right-hand-side
	b := []float64{8.0, 45.0, -3.0, 3.0, 19.0}

	// solve
	x, err := la.SolveRealLinSys(&A, b)
	if err != nil {
		io.Pfred("solver failed:\n%v", err)
		return
	}

	// output
	la.PrintMat("a", A.ToMatrix(nil).ToDense(), "%5g", false)
	la.PrintVec("b", b, "%v ", false)
	la.PrintVec("x", x, "%v ", false)
}
Beispiel #2
0
func CompareJac(tst *testing.T, ffcn Cb_f, Jfcn Cb_J, x []float64, tol float64, distr bool) {
	n := len(x)
	// numerical
	fx := make([]float64, n)
	w := make([]float64, n) // workspace
	ffcn(fx, x)
	var Jnum la.Triplet
	Jnum.Init(n, n, n*n)
	Jacobian(&Jnum, ffcn, x, fx, w, distr)
	jn := Jnum.ToMatrix(nil)
	// analytical
	var Jana la.Triplet
	Jana.Init(n, n, n*n)
	Jfcn(&Jana, x)
	ja := Jana.ToMatrix(nil)
	// compare
	//la.PrintMat(fmt.Sprintf("Jana(%d)",mpi.Rank()), ja.ToDense(), "%13.6f", false)
	//la.PrintMat(fmt.Sprintf("Jnum(%d)",mpi.Rank()), jn.ToDense(), "%13.6f", false)
	max_diff := la.MatMaxDiff(jn.ToDense(), ja.ToDense())
	if max_diff > tol {
		tst.Errorf("max_diff = %g\n", max_diff)
	} else {
		io.Pf("max_diff = %g\n", max_diff)
	}
}
Beispiel #3
0
func main() {

	// input matrix in Triplet format
	// including repeated positions. e.g. (0,0)
	var A la.Triplet
	A.Init(5, 5, 13)
	A.Put(0, 0, 1.0) // << repeated
	A.Put(0, 0, 1.0) // << repeated
	A.Put(1, 0, 3.0)
	A.Put(0, 1, 3.0)
	A.Put(2, 1, -1.0)
	A.Put(4, 1, 4.0)
	A.Put(1, 2, 4.0)
	A.Put(2, 2, -3.0)
	A.Put(3, 2, 1.0)
	A.Put(4, 2, 2.0)
	A.Put(2, 3, 2.0)
	A.Put(1, 4, 6.0)
	A.Put(4, 4, 1.0)

	// right-hand-side
	b := []float64{8.0, 45.0, -3.0, 3.0, 19.0}

	// allocate solver
	lis := la.GetSolver("umfpack")
	defer lis.Clean()

	// info
	symmetric := false
	verbose := false
	timing := false

	// initialise solver (R)eal
	err := lis.InitR(&A, symmetric, verbose, timing)
	if err != nil {
		io.Pfred("solver failed:\n%v", err)
		return
	}

	// factorise
	err = lis.Fact()
	if err != nil {
		io.Pfred("solver failed:\n%v", err)
		return
	}

	// solve (R)eal
	var dummy bool
	x := make([]float64, len(b))
	err = lis.SolveR(x, b, dummy) // x := inv(a) * b
	if err != nil {
		io.Pfred("solver failed:\n%v", err)
		return
	}

	// output
	la.PrintMat("a", A.ToMatrix(nil).ToDense(), "%5g", false)
	la.PrintVec("b", b, "%v ", false)
	la.PrintVec("x", x, "%v ", false)
}
Beispiel #4
0
// CompareJacMpi compares Jacobian matrix (e.g. for testing)
func CompareJacMpi(tst *testing.T, ffcn Cb_f, Jfcn Cb_J, x []float64, tol float64, distr bool) {

	// numerical
	n := len(x)
	fx := make([]float64, n)
	w := make([]float64, n) // workspace
	ffcn(fx, x)
	var Jnum la.Triplet
	Jnum.Init(n, n, n*n)
	JacobianMpi(&Jnum, ffcn, x, fx, w, distr)
	jn := Jnum.ToMatrix(nil)

	// analytical
	var Jana la.Triplet
	Jana.Init(n, n, n*n)
	Jfcn(&Jana, x)
	ja := Jana.ToMatrix(nil)

	// compare
	max_diff := la.MatMaxDiff(jn.ToDense(), ja.ToDense())
	if max_diff > tol {
		tst.Errorf("max_diff = %g\n", max_diff)
	} else {
		io.Pf("max_diff = %g\n", max_diff)
	}
}
Beispiel #5
0
// CheckJ check Jacobian matrix
//  Ouptut: cnd -- condition number (with Frobenius norm)
func (o *NlSolver) CheckJ(x []float64, tol float64, chkJnum, silent bool) (cnd float64, err error) {

	// Jacobian matrix
	var Jmat [][]float64
	if o.useDn {
		Jmat = la.MatAlloc(o.neq, o.neq)
		err = o.JfcnDn(Jmat, x)
		if err != nil {
			return 0, chk.Err(_nls_err5, "dense", err.Error())
		}
	} else {
		if o.numJ {
			err = Jacobian(&o.Jtri, o.Ffcn, x, o.fx, o.w, false)
			if err != nil {
				return 0, chk.Err(_nls_err5, "sparse", err.Error())
			}
		} else {
			err = o.JfcnSp(&o.Jtri, x)
			if err != nil {
				return 0, chk.Err(_nls_err5, "sparse(num)", err.Error())
			}
		}
		Jmat = o.Jtri.ToMatrix(nil).ToDense()
	}
	//la.PrintMat("J", Jmat, "%23g", false)

	// condition number
	cnd, err = la.MatCondG(Jmat, "F", 1e-10)
	if err != nil {
		return cnd, chk.Err(_nls_err6, err.Error())
	}
	if math.IsInf(cnd, 0) || math.IsNaN(cnd) {
		return cnd, chk.Err(_nls_err7, cnd)
	}

	// numerical Jacobian
	if !chkJnum {
		return
	}
	var Jtmp la.Triplet
	ws := make([]float64, o.neq)
	err = o.Ffcn(o.fx, x)
	if err != nil {
		return
	}
	Jtmp.Init(o.neq, o.neq, o.neq*o.neq)
	Jacobian(&Jtmp, o.Ffcn, x, o.fx, ws, false)
	Jnum := Jtmp.ToMatrix(nil).ToDense()
	for i := 0; i < o.neq; i++ {
		for j := 0; j < o.neq; j++ {
			chk.PrintAnaNum(io.Sf("J[%d][%d]", i, j), tol, Jmat[i][j], Jnum[i][j], !silent)
		}
	}
	maxdiff := la.MatMaxDiff(Jmat, Jnum)
	if maxdiff > tol {
		err = chk.Err(_nls_err8, maxdiff)
	}
	return
}
Beispiel #6
0
/*  Jacobian
    ========
        Calculates (with N=n-1):
            df0dx0, df0dx1, df0dx2, ... df0dxN
            df1dx0, df1dx1, df1dx2, ... df1dxN
                 . . . . . . . . . . . . .
            dfNdx0, dfNdx1, dfNdx2, ... dfNdxN
    INPUT:
        ffcn : f(x) function
        x    : station where dfdx has to be calculated
        fx   : f @ x
        w    : workspace with size == n == len(x)
    RETURNS:
        J : dfdx @ x [must be pre-allocated]        */
func Jacobian(J *la.Triplet, ffcn Cb_f, x, fx, w []float64, distr bool) (err error) {
	ndim := len(x)
	start, endp1 := 0, ndim
	if distr {
		id, sz := mpi.Rank(), mpi.Size()
		start, endp1 = (id*ndim)/sz, ((id+1)*ndim)/sz
		if J.Max() == 0 {
			J.Init(ndim, ndim, (endp1-start)*ndim)
		}
	} else {
		if J.Max() == 0 {
			J.Init(ndim, ndim, ndim*ndim)
		}
	}
	J.Start()
	// NOTE: cannot split calculation by columns unless the f function is
	//       independently calculated by each MPI processor.
	//       Otherwise, the AllReduce in f calculation would
	//       join pieces of f from different processors calculated for
	//       different x values (δx[col] from different columns).
	/*
	   for col := start; col < endp1; col++ {
	       xsafe := x[col]
	       delta := math.Sqrt(EPS * max(CTE1, math.Abs(xsafe)))
	       x[col] = xsafe + delta
	       ffcn(w, x) // fnew
	       io.Pforan("x = %v, f = %v\n", x, w)
	       for row := 0; row < ndim; row++ {
	           J.Put(row, col, (w[row]-fx[row])/delta)
	       }
	       x[col] = xsafe
	   }
	*/
	var df float64
	for col := 0; col < ndim; col++ {
		xsafe := x[col]
		delta := math.Sqrt(EPS * max(CTE1, math.Abs(xsafe)))
		x[col] = xsafe + delta
		err = ffcn(w, x) // w := f(x+δx[col])
		if err != nil {
			return
		}
		for row := start; row < endp1; row++ {
			df = w[row] - fx[row]
			//if math.Abs(df) > EPS {
			J.Put(row, col, df/delta)
			//}
		}
		x[col] = xsafe
	}
	return
}
Beispiel #7
0
func main() {

	mpi.Start(false)
	defer func() {
		mpi.Stop(false)
	}()

	if mpi.Rank() == 0 {
		chk.PrintTitle("Test SumToRoot 01")
	}

	M := [][]float64{
		{1000, 1000, 1000, 1011, 1021, 1000},
		{1000, 1000, 1000, 1012, 1022, 1000},
		{1000, 1000, 1000, 1013, 1023, 1000},
		{1011, 1012, 1013, 1000, 1000, 1000},
		{1021, 1022, 1023, 1000, 1000, 1000},
		{1000, 1000, 1000, 1000, 1000, 1000},
	}

	id, sz, m := mpi.Rank(), mpi.Size(), len(M)
	start, endp1 := (id*m)/sz, ((id+1)*m)/sz

	if sz > 6 {
		chk.Panic("this test works with at most 6 processors")
	}

	var J la.Triplet
	J.Init(m, m, m*m)
	for i := start; i < endp1; i++ {
		for j := 0; j < m; j++ {
			J.Put(i, j, M[i][j])
		}
	}
	la.PrintMat(fmt.Sprintf("J @ proc # %d", id), J.ToMatrix(nil).ToDense(), "%10.1f", false)

	la.SpTriSumToRoot(&J)
	var tst testing.T
	if mpi.Rank() == 0 {
		chk.Matrix(&tst, "J @ proc 0", 1.0e-17, J.ToMatrix(nil).ToDense(), [][]float64{
			{1000, 1000, 1000, 1011, 1021, 1000},
			{1000, 1000, 1000, 1012, 1022, 1000},
			{1000, 1000, 1000, 1013, 1023, 1000},
			{1011, 1012, 1013, 1000, 1000, 1000},
			{1021, 1022, 1023, 1000, 1000, 1000},
			{1000, 1000, 1000, 1000, 1000, 1000},
		})
	}
}
Beispiel #8
0
func main() {

	mpi.Start(false)
	defer func() {
		mpi.Stop(false)
	}()

	myrank := mpi.Rank()
	if myrank == 0 {
		chk.PrintTitle("Test MUMPS Sol 02")
	}

	ndim := 10
	id, sz := mpi.Rank(), mpi.Size()
	start, endp1 := (id*ndim)/sz, ((id+1)*ndim)/sz

	if mpi.Size() > ndim {
		chk.Panic("the number of processors must be smaller than or equal to %d", ndim)
	}

	b := make([]float64, ndim)
	var t la.Triplet
	t.Init(ndim, ndim, ndim*ndim)

	for i := start; i < endp1; i++ {
		j := i
		if i > 0 {
			j = i - 1
		}
		for ; j < ndim; j++ {
			val := 10.0 - float64(j)
			if i > j {
				val -= 1.0
			}
			t.Put(i, j, val)
		}
		b[i] = float64(i + 1)
	}

	x_correct := []float64{-1, 8, -65, 454, -2725, 13624, -54497, 163490, -326981, 326991}
	sum_b_to_root := true
	la.RunMumpsTestR(&t, 1e-4, b, x_correct, sum_b_to_root)
}
func main() {

	mpi.Start(false)
	defer func() {
		mpi.Stop(false)
	}()

	myrank := mpi.Rank()
	if myrank == 0 {
		chk.PrintTitle("Test MUMPS Sol 01a")
	}

	var t la.Triplet
	switch mpi.Size() {
	case 1:
		t.Init(5, 5, 13)
		t.Put(0, 0, 1.0)
		t.Put(0, 0, 1.0)
		t.Put(1, 0, 3.0)
		t.Put(0, 1, 3.0)
		t.Put(2, 1, -1.0)
		t.Put(4, 1, 4.0)
		t.Put(1, 2, 4.0)
		t.Put(2, 2, -3.0)
		t.Put(3, 2, 1.0)
		t.Put(4, 2, 2.0)
		t.Put(2, 3, 2.0)
		t.Put(1, 4, 6.0)
		t.Put(4, 4, 1.0)
	case 2:
		if myrank == 0 {
			t.Init(5, 5, 6)
			t.Put(0, 0, 1.0)
			t.Put(0, 0, 1.0)
			t.Put(1, 0, 3.0)
			t.Put(0, 1, 3.0)
			t.Put(2, 1, -1.0)
			t.Put(4, 1, 4.0)
		} else {
			t.Init(5, 5, 7)
			t.Put(1, 2, 4.0)
			t.Put(2, 2, -3.0)
			t.Put(3, 2, 1.0)
			t.Put(4, 2, 2.0)
			t.Put(2, 3, 2.0)
			t.Put(1, 4, 6.0)
			t.Put(4, 4, 1.0)
		}
	default:
		chk.Panic("this test needs 1 or 2 procs")
	}

	b := []float64{8.0, 45.0, -3.0, 3.0, 19.0}
	x_correct := []float64{1, 2, 3, 4, 5}
	sum_b_to_root := false
	la.RunMumpsTestR(&t, 1e-14, b, x_correct, sum_b_to_root)
}
Beispiel #10
0
// Jacobian computes Jacobian (sparse) matrix
//      Calculates (with N=n-1):
//          df0dx0, df0dx1, df0dx2, ... df0dxN
//          df1dx0, df1dx1, df1dx2, ... df1dxN
//               . . . . . . . . . . . . .
//          dfNdx0, dfNdx1, dfNdx2, ... dfNdxN
//  INPUT:
//      ffcn : f(x) function
//      x    : station where dfdx has to be calculated
//      fx   : f @ x
//      w    : workspace with size == n == len(x)
//  RETURNS:
//      J : dfdx @ x [must be pre-allocated]
func Jacobian(J *la.Triplet, ffcn Cb_f, x, fx, w []float64) (err error) {
	ndim := len(x)
	start, endp1 := 0, ndim
	if J.Max() == 0 {
		J.Init(ndim, ndim, ndim*ndim)
	}
	J.Start()
	var df float64
	for col := 0; col < ndim; col++ {
		xsafe := x[col]
		delta := math.Sqrt(EPS * max(CTE1, math.Abs(xsafe)))
		x[col] = xsafe + delta
		err = ffcn(w, x) // w := f(x+δx[col])
		if err != nil {
			return
		}
		for row := start; row < endp1; row++ {
			df = w[row] - fx[row]
			J.Put(row, col, df/delta)
		}
		x[col] = xsafe
	}
	return
}
Beispiel #11
0
func InitK11andK12(K11, K12 *la.Triplet, e *Equations) {
	K11.Init(e.N1, e.N1, e.N1*5)
	K12.Init(e.N1, e.N2, e.N1*5)
}
Beispiel #12
0
func main() {

	mpi.Start(false)
	defer func() {
		mpi.Stop(false)
	}()

	if mpi.Rank() == 0 {
		chk.PrintTitle("Test ODE 04b (MPI)")
		io.Pfcyan("Hairer-Wanner VII-p376 Transistor Amplifier (MPI)\n")
		io.Pfcyan("(from E Hairer's website, not the system in the book)\n")
	}
	if mpi.Size() != 3 {
		chk.Panic(">> error: this test requires 3 MPI processors\n")
		return
	}

	// RIGHT-HAND SIDE OF THE AMPLIFIER PROBLEM
	w := make([]float64, 8) // workspace
	fcn := func(f []float64, x float64, y []float64, args ...interface{}) error {
		d := args[0].(*HWtransData)
		UET := d.UE * math.Sin(d.W*x)
		FAC1 := d.BETA * (math.Exp((y[3]-y[2])/d.UF) - 1.0)
		FAC2 := d.BETA * (math.Exp((y[6]-y[5])/d.UF) - 1.0)
		la.VecFill(f, 0)
		switch mpi.Rank() {
		case 0:
			f[0] = y[0] / d.R9
		case 1:
			f[1] = (y[1]-d.UB)/d.R8 + d.ALPHA*FAC1
			f[2] = y[2]/d.R7 - FAC1
		case 2:
			f[3] = y[3]/d.R5 + (y[3]-d.UB)/d.R6 + (1.0-d.ALPHA)*FAC1
			f[4] = (y[4]-d.UB)/d.R4 + d.ALPHA*FAC2
			f[5] = y[5]/d.R3 - FAC2
			f[6] = y[6]/d.R1 + (y[6]-d.UB)/d.R2 + (1.0-d.ALPHA)*FAC2
			f[7] = (y[7] - UET) / d.R0
		}
		mpi.AllReduceSum(f, w)
		return nil
	}

	// JACOBIAN OF THE AMPLIFIER PROBLEM
	jac := func(dfdy *la.Triplet, x float64, y []float64, args ...interface{}) error {
		d := args[0].(*HWtransData)
		FAC14 := d.BETA * math.Exp((y[3]-y[2])/d.UF) / d.UF
		FAC27 := d.BETA * math.Exp((y[6]-y[5])/d.UF) / d.UF
		if dfdy.Max() == 0 {
			dfdy.Init(8, 8, 16)
		}
		NU := 2
		dfdy.Start()
		switch mpi.Rank() {
		case 0:
			dfdy.Put(2+0-NU, 0, 1.0/d.R9)
			dfdy.Put(2+1-NU, 1, 1.0/d.R8)
			dfdy.Put(1+2-NU, 2, -d.ALPHA*FAC14)
			dfdy.Put(0+3-NU, 3, d.ALPHA*FAC14)
			dfdy.Put(2+2-NU, 2, 1.0/d.R7+FAC14)
		case 1:
			dfdy.Put(1+3-NU, 3, -FAC14)
			dfdy.Put(2+3-NU, 3, 1.0/d.R5+1.0/d.R6+(1.0-d.ALPHA)*FAC14)
			dfdy.Put(3+2-NU, 2, -(1.0-d.ALPHA)*FAC14)
			dfdy.Put(2+4-NU, 4, 1.0/d.R4)
			dfdy.Put(1+5-NU, 5, -d.ALPHA*FAC27)
		case 2:
			dfdy.Put(0+6-NU, 6, d.ALPHA*FAC27)
			dfdy.Put(2+5-NU, 5, 1.0/d.R3+FAC27)
			dfdy.Put(1+6-NU, 6, -FAC27)
			dfdy.Put(2+6-NU, 6, 1.0/d.R1+1.0/d.R2+(1.0-d.ALPHA)*FAC27)
			dfdy.Put(3+5-NU, 5, -(1.0-d.ALPHA)*FAC27)
			dfdy.Put(2+7-NU, 7, 1.0/d.R0)
		}
		return nil
	}

	// MATRIX "M"
	c1, c2, c3, c4, c5 := 1.0e-6, 2.0e-6, 3.0e-6, 4.0e-6, 5.0e-6
	var M la.Triplet
	M.Init(8, 8, 14)
	M.Start()
	NU := 1
	switch mpi.Rank() {
	case 0:
		M.Put(1+0-NU, 0, -c5)
		M.Put(0+1-NU, 1, c5)
		M.Put(2+0-NU, 0, c5)
		M.Put(1+1-NU, 1, -c5)
		M.Put(1+2-NU, 2, -c4)
		M.Put(1+3-NU, 3, -c3)
	case 1:
		M.Put(0+4-NU, 4, c3)
		M.Put(2+3-NU, 3, c3)
		M.Put(1+4-NU, 4, -c3)
	case 2:
		M.Put(1+5-NU, 5, -c2)
		M.Put(1+6-NU, 6, -c1)
		M.Put(0+7-NU, 7, c1)
		M.Put(2+6-NU, 6, c1)
		M.Put(1+7-NU, 7, -c1)
	}

	// WRITE FILE FUNCTION
	idxstp := 1
	var b bytes.Buffer
	out := func(first bool, dx, x float64, y []float64, args ...interface{}) error {
		if mpi.Rank() == 0 {
			if first {
				fmt.Fprintf(&b, "%6s%23s%23s%23s%23s%23s%23s%23s%23s%23s\n", "ns", "x", "y0", "y1", "y2", "y3", "y4", "y5", "y6", "y7")
			}
			fmt.Fprintf(&b, "%6d%23.15E", idxstp, x)
			for j := 0; j < len(y); j++ {
				fmt.Fprintf(&b, "%23.15E", y[j])
			}
			fmt.Fprintf(&b, "\n")
			idxstp += 1
		}
		return nil
	}
	defer func() {
		if mpi.Rank() == 0 {
			io.WriteFileD("/tmp/gosl", "hwamplifierB.res", &b)
		}
	}()

	// INITIAL DATA
	D, xa, xb, ya := HWtransIni()

	// SET ODE SOLVER
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	ndim := len(ya)
	//numjac := true
	numjac := false
	var osol ode.ODE

	osol.Pll = true

	if numjac {
		osol.Init(method, ndim, fcn, nil, &M, out, silent)
	} else {
		osol.Init(method, ndim, fcn, jac, &M, out, silent)
	}
	osol.IniH = 1.0e-6 // initial step size

	// SET TOLERANCES
	atol, rtol := 1e-11, 1e-5
	osol.SetTol(atol, rtol)

	// RUN
	t0 := time.Now()
	if fixstp {
		osol.Solve(ya, xa, xb, 0.01, fixstp, &D)
	} else {
		osol.Solve(ya, xa, xb, xb-xa, fixstp, &D)
	}
	if mpi.Rank() == 0 {
		io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))
	}
}
Beispiel #13
0
func Test_linipm02(tst *testing.T) {

	//verbose()
	chk.PrintTitle("linipm02")

	// linear program
	//   min   2*x0 +   x1
	//   s.t.   -x0 +   x1 ≤ 1
	//           x0 +   x1 ≥ 2   →  -x0 - x1 ≤ -2
	//           x0 - 2*x1 ≤ 4
	//         x1 ≥ 0
	// standard (step 1) add slack
	//   s.t.   -x0 +   x1 + x2           = 1
	//          -x0 -   x1      + x3      = -2
	//           x0 - 2*x1           + x4 = 4
	// standard (step 2)
	//    replace x0 := x0_ - x5
	//    because it's unbounded
	//    min  2*x0_ +   x1                - 2*x5
	//    s.t.  -x0_ +   x1 + x2           +   x5 = 1
	//          -x0_ -   x1      + x3      +   x5 = -2
	//           x0_ - 2*x1           + x4 -   x5 = 4
	//         x0_,x1,x2,x3,x4,x5 ≥ 0
	var T la.Triplet
	T.Init(3, 6, 12)
	T.Put(0, 0, -1)
	T.Put(0, 1, 1)
	T.Put(0, 2, 1)
	T.Put(0, 5, 1)
	T.Put(1, 0, -1)
	T.Put(1, 1, -1)
	T.Put(1, 3, 1)
	T.Put(1, 5, 1)
	T.Put(2, 0, 1)
	T.Put(2, 1, -2)
	T.Put(2, 4, 1)
	T.Put(2, 5, -1)
	Am := T.ToMatrix(nil)
	A := Am.ToDense()
	c := []float64{2, 1, 0, 0, 0, -2}
	b := []float64{1, -2, 4}

	// print LP
	la.PrintMat("A", A, "%6g", false)
	la.PrintVec("b", b, "%6g", false)
	la.PrintVec("c", c, "%6g", false)
	io.Pf("\n")

	// solve LP
	var ipm LinIpm
	defer ipm.Clean()
	ipm.Init(Am, b, c, nil)
	err := ipm.Solve(chk.Verbose)
	if err != nil {
		tst.Errorf("ipm failed:\n%v", err)
		return
	}

	// check
	io.Pf("\n")
	bres := make([]float64, len(b))
	la.MatVecMul(bres, 1, A, ipm.X)
	io.Pforan("bres = %v\n", bres)
	chk.Vector(tst, "A*x=b", 1e-8, bres, b)

	// fix and check x
	x := ipm.X[:2]
	x[0] -= ipm.X[5]
	io.Pforan("x = %v\n", x)
	chk.Vector(tst, "x", 1e-8, x, []float64{0.5, 1.5})

	// plot
	if true && chk.Verbose {
		f := func(x []float64) float64 {
			return c[0]*x[0] + c[1]*x[1]
		}
		g := func(x []float64, i int) float64 {
			return A[i][0]*x[0] + A[i][1]*x[1] - b[i]
		}
		np := 41
		vmin, vmax := []float64{-2.0, -2.0}, []float64{2.0, 2.0}
		PlotTwoVarsContour("/tmp/gosl", "test_linipm02", x, np, nil, true, vmin, vmax, f,
			func(x []float64) float64 { return g(x, 0) },
			func(x []float64) float64 { return g(x, 1) },
		)
	}
}
Beispiel #14
0
func main() {

	mpi.Start(false)
	defer func() {
		mpi.Stop(false)
	}()

	myrank := mpi.Rank()
	if myrank == 0 {
		chk.PrintTitle("Test MUMPS Sol 01b")
	}

	var t la.Triplet
	b := []float64{8.0, 45.0, -3.0, 3.0, 19.0}
	switch mpi.Size() {
	case 1:
		t.Init(5, 5, 13)
		t.Put(0, 0, 1.0)
		t.Put(0, 0, 1.0)
		t.Put(1, 0, 3.0)
		t.Put(0, 1, 3.0)
		t.Put(2, 1, -1.0)
		t.Put(4, 1, 4.0)
		t.Put(1, 2, 4.0)
		t.Put(2, 2, -3.0)
		t.Put(3, 2, 1.0)
		t.Put(4, 2, 2.0)
		t.Put(2, 3, 2.0)
		t.Put(1, 4, 6.0)
		t.Put(4, 4, 1.0)
	case 2:
		la.VecFill(b, 0)
		if myrank == 0 {
			t.Init(5, 5, 8)
			t.Put(0, 0, 1.0)
			t.Put(0, 0, 1.0)
			t.Put(1, 0, 3.0)
			t.Put(0, 1, 3.0)
			t.Put(2, 1, -1.0)
			t.Put(4, 1, 1.0)
			t.Put(4, 1, 1.5)
			t.Put(4, 1, 1.5)
			b[0] = 8.0
			b[1] = 40.0
			b[2] = 1.5
		} else {
			t.Init(5, 5, 8)
			t.Put(1, 2, 4.0)
			t.Put(2, 2, -3.0)
			t.Put(3, 2, 1.0)
			t.Put(4, 2, 2.0)
			t.Put(2, 3, 2.0)
			t.Put(1, 4, 6.0)
			t.Put(4, 4, 0.5)
			t.Put(4, 4, 0.5)
			b[1] = 5.0
			b[2] = -4.5
			b[3] = 3.0
			b[4] = 19.0
		}
	default:
		chk.Panic("this test needs 1 or 2 procs")
	}

	x_correct := []float64{1, 2, 3, 4, 5}
	sum_b_to_root := true
	la.RunMumpsTestR(&t, 1e-14, b, x_correct, sum_b_to_root)
}
Beispiel #15
0
func main() {

	mpi.Start(false)
	defer func() {
		mpi.Stop(false)
	}()

	if mpi.Rank() == 0 {
		chk.PrintTitle("ode04: Hairer-Wanner VII-p376 Transistor Amplifier\n")
	}
	if mpi.Size() != 3 {
		chk.Panic(">> error: this test requires 3 MPI processors\n")
		return
	}

	// data
	UE, UB, UF, ALPHA, BETA := 0.1, 6.0, 0.026, 0.99, 1.0e-6
	R0, R1, R2, R3, R4, R5 := 1000.0, 9000.0, 9000.0, 9000.0, 9000.0, 9000.0
	R6, R7, R8, R9 := 9000.0, 9000.0, 9000.0, 9000.0
	W := 2.0 * 3.141592654 * 100.0

	// initial values
	xa := 0.0
	ya := []float64{0.0,
		UB,
		UB / (R6/R5 + 1.0),
		UB / (R6/R5 + 1.0),
		UB,
		UB / (R2/R1 + 1.0),
		UB / (R2/R1 + 1.0),
		0.0}

	// endpoint of integration
	xb := 0.05
	//xb = 0.0123 // OK
	//xb = 0.01235 // !OK

	// right-hand side of the amplifier problem
	w := make([]float64, 8) // workspace
	fcn := func(f []float64, dx, x float64, y []float64, args ...interface{}) error {
		UET := UE * math.Sin(W*x)
		FAC1 := BETA * (math.Exp((y[3]-y[2])/UF) - 1.0)
		FAC2 := BETA * (math.Exp((y[6]-y[5])/UF) - 1.0)
		la.VecFill(f, 0)
		switch mpi.Rank() {
		case 0:
			f[0] = y[0] / R9
		case 1:
			f[1] = (y[1]-UB)/R8 + ALPHA*FAC1
			f[2] = y[2]/R7 - FAC1
		case 2:
			f[3] = y[3]/R5 + (y[3]-UB)/R6 + (1.0-ALPHA)*FAC1
			f[4] = (y[4]-UB)/R4 + ALPHA*FAC2
			f[5] = y[5]/R3 - FAC2
			f[6] = y[6]/R1 + (y[6]-UB)/R2 + (1.0-ALPHA)*FAC2
			f[7] = (y[7] - UET) / R0
		}
		mpi.AllReduceSum(f, w)
		return nil
	}

	// Jacobian of the amplifier problem
	jac := func(dfdy *la.Triplet, dx, x float64, y []float64, args ...interface{}) error {
		FAC14 := BETA * math.Exp((y[3]-y[2])/UF) / UF
		FAC27 := BETA * math.Exp((y[6]-y[5])/UF) / UF
		if dfdy.Max() == 0 {
			dfdy.Init(8, 8, 16)
		}
		NU := 2
		dfdy.Start()
		switch mpi.Rank() {
		case 0:
			dfdy.Put(2+0-NU, 0, 1.0/R9)
			dfdy.Put(2+1-NU, 1, 1.0/R8)
			dfdy.Put(1+2-NU, 2, -ALPHA*FAC14)
			dfdy.Put(0+3-NU, 3, ALPHA*FAC14)
			dfdy.Put(2+2-NU, 2, 1.0/R7+FAC14)
		case 1:
			dfdy.Put(1+3-NU, 3, -FAC14)
			dfdy.Put(2+3-NU, 3, 1.0/R5+1.0/R6+(1.0-ALPHA)*FAC14)
			dfdy.Put(3+2-NU, 2, -(1.0-ALPHA)*FAC14)
			dfdy.Put(2+4-NU, 4, 1.0/R4)
			dfdy.Put(1+5-NU, 5, -ALPHA*FAC27)
		case 2:
			dfdy.Put(0+6-NU, 6, ALPHA*FAC27)
			dfdy.Put(2+5-NU, 5, 1.0/R3+FAC27)
			dfdy.Put(1+6-NU, 6, -FAC27)
			dfdy.Put(2+6-NU, 6, 1.0/R1+1.0/R2+(1.0-ALPHA)*FAC27)
			dfdy.Put(3+5-NU, 5, -(1.0-ALPHA)*FAC27)
			dfdy.Put(2+7-NU, 7, 1.0/R0)
		}
		return nil
	}

	// matrix "M"
	c1, c2, c3, c4, c5 := 1.0e-6, 2.0e-6, 3.0e-6, 4.0e-6, 5.0e-6
	var M la.Triplet
	M.Init(8, 8, 14)
	M.Start()
	NU := 1
	switch mpi.Rank() {
	case 0:
		M.Put(1+0-NU, 0, -c5)
		M.Put(0+1-NU, 1, c5)
		M.Put(2+0-NU, 0, c5)
		M.Put(1+1-NU, 1, -c5)
		M.Put(1+2-NU, 2, -c4)
		M.Put(1+3-NU, 3, -c3)
	case 1:
		M.Put(0+4-NU, 4, c3)
		M.Put(2+3-NU, 3, c3)
		M.Put(1+4-NU, 4, -c3)
	case 2:
		M.Put(1+5-NU, 5, -c2)
		M.Put(1+6-NU, 6, -c1)
		M.Put(0+7-NU, 7, c1)
		M.Put(2+6-NU, 6, c1)
		M.Put(1+7-NU, 7, -c1)
	}

	// flags
	silent := false
	fixstp := false
	//method := "Dopri5"
	method := "Radau5"
	ndim := len(ya)
	numjac := false

	// structure to hold numerical results
	res := ode.Results{Method: method}

	// ODE solver
	var osol ode.Solver
	osol.Pll = true

	// solve problem
	if numjac {
		osol.Init(method, ndim, fcn, nil, &M, ode.SimpleOutput, silent)
	} else {
		osol.Init(method, ndim, fcn, jac, &M, ode.SimpleOutput, silent)
	}
	osol.IniH = 1.0e-6 // initial step size

	// set tolerances
	atol, rtol := 1e-11, 1e-5
	osol.SetTol(atol, rtol)

	// run
	t0 := time.Now()
	if fixstp {
		osol.Solve(ya, xa, xb, 0.01, fixstp, &res)
	} else {
		osol.Solve(ya, xa, xb, xb-xa, fixstp, &res)
	}

	// plot
	if mpi.Rank() == 0 {
		io.Pfmag("elapsed time = %v\n", time.Now().Sub(t0))
		plt.SetForEps(2.0, 400)
		args := "'b-', marker='.', lw=1, clip_on=0"
		ode.Plot("/tmp/gosl/ode", "hwamplifier_mpi.eps", &res, nil, xa, xb, "", args, func() {
			_, T, err := io.ReadTable("data/radau5_hwamplifier.dat")
			if err != nil {
				chk.Panic("%v", err)
			}
			for j := 0; j < ndim; j++ {
				plt.Subplot(ndim+1, 1, j+1)
				plt.Plot(T["x"], T[io.Sf("y%d", j)], "'k+',label='reference',ms=10")
			}
		})
	}
}
Beispiel #16
0
func TestJacobian03(tst *testing.T) {

	//verbose()
	chk.PrintTitle("TestJacobian 03")

	// grid
	var g fdm.Grid2D
	//g.Init(1.0, 1.0, 4, 4)
	g.Init(1.0, 1.0, 6, 6)
	//g.Init(1.0, 1.0, 11, 11)

	// equations numbering
	var e fdm.Equations
	peq := utl.IntUnique(g.L, g.R, g.B, g.T)
	e.Init(g.N, peq)

	// K11 and K12
	var K11, K12 la.Triplet
	fdm.InitK11andK12(&K11, &K12, &e)

	// assembly
	F1 := make([]float64, e.N1)
	fdm.Assemble(&K11, &K12, F1, nil, &g, &e)

	// prescribed values
	U2 := make([]float64, e.N2)
	for _, eq := range g.L {
		U2[e.FR2[eq]] = 50.0
	}
	for _, eq := range g.R {
		U2[e.FR2[eq]] = 0.0
	}
	for _, eq := range g.B {
		U2[e.FR2[eq]] = 0.0
	}
	for _, eq := range g.T {
		U2[e.FR2[eq]] = 50.0
	}

	// functions
	k11 := K11.ToMatrix(nil)
	k12 := K12.ToMatrix(nil)
	ffcn := func(fU1, U1 []float64) error { // K11*U1 + K12*U2 - F1
		la.VecCopy(fU1, -1, F1)            // fU1 := (-F1)
		la.SpMatVecMulAdd(fU1, 1, k11, U1) // fU1 += K11*U1
		la.SpMatVecMulAdd(fU1, 1, k12, U2) // fU1 += K12*U2
		return nil
	}
	Jfcn := func(dfU1dU1 *la.Triplet, U1 []float64) error {
		fdm.Assemble(dfU1dU1, &K12, F1, nil, &g, &e)
		return nil
	}
	U1 := make([]float64, e.N1)
	CompareJac(tst, ffcn, Jfcn, U1, 0.0075)

	print_jac := false
	if print_jac {
		W1 := make([]float64, e.N1)
		fU1 := make([]float64, e.N1)
		ffcn(fU1, U1)
		var Jnum la.Triplet
		Jnum.Init(e.N1, e.N1, e.N1*e.N1)
		Jacobian(&Jnum, ffcn, U1, fU1, W1)
		la.PrintMat("K11 ", K11.ToMatrix(nil).ToDense(), "%g ", false)
		la.PrintMat("Jnum", Jnum.ToMatrix(nil).ToDense(), "%g ", false)
	}

	test_ffcn := false
	if test_ffcn {
		Uc := []float64{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 50.0, 25.0, 325.0 / 22.0, 100.0 / 11.0, 50.0 / 11.0,
			0.0, 50.0, 775.0 / 22.0, 25.0, 375.0 / 22.0, 100.0 / 11.0, 0.0, 50.0, 450.0 / 11.0, 725.0 / 22.0,
			25.0, 325.0 / 22.0, 0.0, 50.0, 500.0 / 11.0, 450.0 / 11.0, 775.0 / 22.0, 25.0, 0.0, 50.0, 50.0,
			50.0, 50.0, 50.0, 50.0,
		}
		for i := 0; i < e.N1; i++ {
			U1[i] = Uc[e.RF1[i]]
		}
		fU1 := make([]float64, e.N1)
		min, max := la.VecMinMax(fU1)
		io.Pf("min/max fU1 = %v\n", min, max)
	}
}
Beispiel #17
0
func Test_linipm01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("linipm01")

	// linear programming problem
	//   min  -4*x0 - 5*x1
	//   s.t.  2*x0 +   x1 ≤ 3
	//           x0 + 2*x1 ≤ 3
	//         x0,x1 ≥ 0
	// standard:
	//         2*x0 +   x1 + x2     = 3
	//           x0 + 2*x1     + x3 = 3
	//         x0,x1,x2,x3 ≥ 0
	var T la.Triplet
	T.Init(2, 4, 6)
	T.Put(0, 0, 2.0)
	T.Put(0, 1, 1.0)
	T.Put(0, 2, 1.0)
	T.Put(1, 0, 1.0)
	T.Put(1, 1, 2.0)
	T.Put(1, 3, 1.0)
	Am := T.ToMatrix(nil)
	A := Am.ToDense()
	c := []float64{-4, -5, 0, 0}
	b := []float64{3, 3}

	// print LP
	la.PrintMat("A", A, "%6g", false)
	la.PrintVec("b", b, "%6g", false)
	la.PrintVec("c", c, "%6g", false)
	io.Pf("\n")

	// solve LP
	var ipm LinIpm
	defer ipm.Clean()
	ipm.Init(Am, b, c, nil)
	err := ipm.Solve(chk.Verbose)
	if err != nil {
		tst.Errorf("ipm failed:\n%v", err)
		return
	}

	// check
	io.Pf("\n")
	io.Pforan("x = %v\n", ipm.X)
	io.Pfcyan("λ = %v\n", ipm.L)
	io.Pforan("s = %v\n", ipm.S)
	x := ipm.X[:2]
	bres := make([]float64, 2)
	la.MatVecMul(bres, 1, A, x)
	io.Pforan("bres = %v\n", bres)
	chk.Vector(tst, "x", 1e-9, x, []float64{1, 1})
	chk.Vector(tst, "A*x=b", 1e-8, bres, b)

	// plot
	if true && chk.Verbose {
		f := func(x []float64) float64 {
			return c[0]*x[0] + c[1]*x[1]
		}
		g := func(x []float64, i int) float64 {
			return A[i][0]*x[0] + A[i][1]*x[1] - b[i]
		}
		np := 41
		vmin, vmax := []float64{-2.0, -2.0}, []float64{2.0, 2.0}
		PlotTwoVarsContour("/tmp/gosl", "test_linipm01", x, np, nil, true, vmin, vmax, f,
			func(x []float64) float64 { return g(x, 0) },
			func(x []float64) float64 { return g(x, 1) },
		)
	}
}