// 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 }
// 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 }