예제 #1
0
// ToMatrix converts a sparse matrix in triplet form to column-compressed form using Umfpack's
// routines. "realloc_a" indicates whether the internal "a" matrix must be reallocated or not,
// for instance, in case the structure of the triplet has changed.
//  INPUT:
//   a -- a previous CCMatrix to be filled in; otherwise, "nil" tells to allocate a new one
//  OUTPUT:
//   the previous "a" matrix or a pointer to a new one
func (t *Triplet) ToMatrix(a *CCMatrix) *CCMatrix {
	if t.pos < 1 {
		chk.Panic(_sparsemat_umfpack_err1, t.pos)
	}
	if a == nil {
		a = new(CCMatrix)
		a.m, a.n, a.nnz = t.m, t.n, t.pos
		a.p = make([]int, a.n+1)
		a.i = make([]int, a.nnz)
		a.x = make([]float64, a.nnz)
	}
	Ti := (*C.LONG)(unsafe.Pointer(&t.i[0]))
	Tj := (*C.LONG)(unsafe.Pointer(&t.j[0]))
	Tx := (*C.double)(unsafe.Pointer(&t.x[0]))
	Ap := (*C.LONG)(unsafe.Pointer(&a.p[0]))
	Ai := (*C.LONG)(unsafe.Pointer(&a.i[0]))
	Ax := (*C.double)(unsafe.Pointer(&a.x[0]))
	status := C.umfpack_dl_triplet_to_col(C.LONG(a.m), C.LONG(a.n), C.LONG(a.nnz), Ti, Tj, Tx, Ap, Ai, Ax, nil)
	if status != C.UMFPACK_OK {
		chk.Panic(_sparsemat_umfpack_err2, Uerr2Text[int(status)])
	}
	return a
}
예제 #2
0
// Fact performs symbolic/numeric factorisation. This method also converts the triplet form
// to the column-compressed form, including the summation of duplicated entries
func (o *LinSolUmfpack) Fact() (err error) {

	// start time
	if o.ton {
		o.tini = time.Now()
	}

	// message
	if o.verb {
		io.Pfgreen("\n . . . . . . . . . . . . . . LinSolUmfpack.Fact . . . . . . . . . . . . . . . \n\n")
	}

	// factorisation
	if o.cmplx {

		// UMFPACK: convert triplet to column-compressed format
		st := C.umfpack_zl_triplet_to_col(C.LONG(o.tC.m), C.LONG(o.tC.n), C.LONG(o.tC.pos), o.ti, o.tj, o.tx, o.tz, o.ap, o.ai, o.ax, o.az, nil)
		if st != C.UMFPACK_OK {
			return chk.Err(_linsol_umfpack_err04, Uerr2Text[int(st)])
		}

		// UMFPACK: symbolic factorisation
		st = C.umfpack_zl_symbolic(C.LONG(o.tC.m), C.LONG(o.tC.n), o.ap, o.ai, o.ax, o.az, &o.usymb, o.uctrl, nil)
		if st != C.UMFPACK_OK {
			return chk.Err(_linsol_umfpack_err05, Uerr2Text[int(st)])
		}

		// UMFPACK: numeric factorisation
		st = C.umfpack_zl_numeric(o.ap, o.ai, o.ax, o.az, o.usymb, &o.unum, o.uctrl, nil)
		if st != C.UMFPACK_OK {
			return chk.Err(_linsol_umfpack_err06, Uerr2Text[int(st)])
		}

	} else {

		// UMFPACK: convert triplet to column-compressed format
		st := C.umfpack_dl_triplet_to_col(C.LONG(o.tR.m), C.LONG(o.tR.n), C.LONG(o.tR.pos), o.ti, o.tj, o.tx, o.ap, o.ai, o.ax, nil)
		if st != C.UMFPACK_OK {
			return chk.Err(_linsol_umfpack_err07, Uerr2Text[int(st)])
		}

		// UMFPACK: symbolic factorisation
		st = C.umfpack_dl_symbolic(C.LONG(o.tR.m), C.LONG(o.tR.n), o.ap, o.ai, o.ax, &o.usymb, o.uctrl, nil)
		if st != C.UMFPACK_OK {
			return chk.Err(_linsol_umfpack_err08, Uerr2Text[int(st)])
		}

		// UMFPACK: numeric factorisation
		st = C.umfpack_dl_numeric(o.ap, o.ai, o.ax, o.usymb, &o.unum, o.uctrl, nil)
		if st != C.UMFPACK_OK {
			return chk.Err(_linsol_umfpack_err09, Uerr2Text[int(st)])
		}

		return

	}

	// duration
	if o.ton {
		io.Pfcyan("%s: Time spent in LinSolUmfpack.Fact  = %v\n", o.name, time.Now().Sub(o.tini))
	}
	return
}