// ToMatrix converts a sparse matrix in triplet form with complex numbers to column-compressed form. // "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 CCMatrixC 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 *TripletC) ToMatrix(a *CCMatrixC) *CCMatrixC { if t.pos < 1 { chk.Panic(_sparsemat_umfpack_err3, t.pos) } if a == nil { a = new(CCMatrixC) 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) a.z = make([]float64, a.nnz) } Ap := (*C.LONG)(unsafe.Pointer(&a.p[0])) Ai := (*C.LONG)(unsafe.Pointer(&a.i[0])) Ax := (*C.double)(unsafe.Pointer(&a.x[0])) Az := (*C.double)(unsafe.Pointer(&a.z[0])) Ti := (*C.LONG)(unsafe.Pointer(&t.i[0])) Tj := (*C.LONG)(unsafe.Pointer(&t.j[0])) var Tx, Tz *C.double if t.xz != nil { x := make([]float64, t.pos) z := make([]float64, t.pos) for k := 0; k < t.pos; k++ { x[k], z[k] = t.xz[k*2], t.xz[k*2+1] } Tx = (*C.double)(unsafe.Pointer(&x[0])) Tz = (*C.double)(unsafe.Pointer(&z[0])) } else { Tx = (*C.double)(unsafe.Pointer(&t.x[0])) Tz = (*C.double)(unsafe.Pointer(&t.z[0])) } status := C.umfpack_zl_triplet_to_col(C.LONG(a.m), C.LONG(a.n), C.LONG(a.nnz), Ti, Tj, Tx, Tz, Ap, Ai, Ax, Az, nil) if status != C.UMFPACK_OK { chk.Panic(_sparsemat_umfpack_err4, 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 }