Ejemplo n.º 1
0
SEXP dgeMatrix_determinant(SEXP x, SEXP logarithm)
{
    int lg = asLogical(logarithm);
    int *dims = INTEGER(GET_SLOT(x, Matrix_DimSym)),
	n = dims[0], sign = 1;
    double modulus = lg ? 0. : 1; /* initialize; = result for n == 0 */

    if (n != dims[1])
	error(_("Determinant requires a square matrix"));
    if (n > 0) {
	SEXP lu = dgeMatrix_LU_(x, /* do not warn about singular LU: */ FALSE);
	int i, *jpvt = INTEGER(GET_SLOT(lu, Matrix_permSym));
	double *luvals = REAL(GET_SLOT(lu, Matrix_xSym));

	for (i = 0; i < n; i++) if (jpvt[i] != (i + 1)) sign = -sign;
	if (lg) {
	    for (i = 0; i < n; i++) {
		double dii = luvals[i*(n + 1)]; /* ith diagonal element */
		modulus += log(dii < 0 ? -dii : dii);
		if (dii < 0) sign = -sign;
	    }
	} else {
	    for (i = 0; i < n; i++)
		modulus *= luvals[i*(n + 1)];
	    if (modulus < 0) {
		modulus = -modulus;
		sign = -sign;
	    }
	}
    }
    return as_det_obj(modulus, lg, sign);
}
Ejemplo n.º 2
0
SEXP dgeMatrix_solve(SEXP a)
{
    /*  compute the 1-norm of the matrix, which is needed
	later for the computation of the reciprocal condition number. */
    double aNorm = get_norm(a, "1");

    /* the LU decomposition : */
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix"))),
	lu = dgeMatrix_LU_(a, TRUE);
    int *dims = INTEGER(GET_SLOT(lu, Matrix_DimSym)),
	*pivot = INTEGER(GET_SLOT(lu, Matrix_permSym));

    /* prepare variables for the dgetri calls */
    double *x, tmp;
    int	info, lwork = -1;


    if (dims[0] != dims[1]) error(_("Solve requires a square matrix"));
    slot_dup(val, lu, Matrix_xSym);
    x = REAL(GET_SLOT(val, Matrix_xSym));
    slot_dup(val, lu, Matrix_DimSym);

    if(dims[0]) /* the dimension is not zero */
    {
        /* is the matrix is *computationally* singular ? */
        double rcond;
        F77_CALL(dgecon)("1", dims, x, dims, &aNorm, &rcond,
                         (double *) R_alloc(4*dims[0], sizeof(double)),
                         (int *) R_alloc(dims[0], sizeof(int)), &info);
        if (info)
            error(_("error [%d] from Lapack 'dgecon()'"), info);
        if(rcond < DOUBLE_EPS)
            error(_("Lapack dgecon(): system computationally singular, reciprocal condition number = %g"),
		  rcond);

        /* only now try the inversion and check if the matrix is *exactly* singular: */
	F77_CALL(dgetri)(dims, x, dims, pivot, &tmp, &lwork, &info);
	lwork = (int) tmp;
	F77_CALL(dgetri)(dims, x, dims, pivot,
			 (double *) R_alloc((size_t) lwork, sizeof(double)),
			 &lwork, &info);
	if (info)
	    error(_("Lapack routine dgetri: system is exactly singular"));
    }
    UNPROTECT(1);
    return val;
}
Ejemplo n.º 3
0
SEXP dgeMatrix_matrix_solve(SEXP a, SEXP b)
{
    SEXP val = PROTECT(dup_mMatrix_as_dgeMatrix(b)),
	lu = PROTECT(dgeMatrix_LU_(a, TRUE));
    int *adims = INTEGER(GET_SLOT(lu, Matrix_DimSym)),
	*bdims = INTEGER(GET_SLOT(val, Matrix_DimSym));
    int info, n = bdims[0], nrhs = bdims[1];

    if (*adims != *bdims || bdims[1] < 1 || *adims < 1 || *adims != adims[1])
	error(_("Dimensions of system to be solved are inconsistent"));
    F77_CALL(dgetrs)("N", &n, &nrhs, REAL(GET_SLOT(lu, Matrix_xSym)), &n,
		     INTEGER(GET_SLOT(lu, Matrix_permSym)),
		     REAL(GET_SLOT(val, Matrix_xSym)), &n, &info);
    if (info)
	error(_("Lapack routine dgetrs: system is exactly singular"));
    UNPROTECT(2);
    return val;
}
Ejemplo n.º 4
0
SEXP dgeMatrix_rcond(SEXP obj, SEXP type)
{
    SEXP LU = PROTECT(dgeMatrix_LU_(obj, FALSE));/* <- not warning about singularity */
    char typnm[] = {'\0', '\0'};
    int *dims = INTEGER(GET_SLOT(LU, Matrix_DimSym)), info;
    double anorm, rcond;

    if (dims[0] != dims[1] || dims[0] < 1) {
	UNPROTECT(1);
	error(_("rcond requires a square, non-empty matrix"));
    }
    typnm[0] = La_rcond_type(CHAR(asChar(type)));
    anorm = get_norm(obj, typnm);
    F77_CALL(dgecon)(typnm,
		     dims, REAL(GET_SLOT(LU, Matrix_xSym)),
		     dims, &anorm, &rcond,
		     (double *) R_alloc(4*dims[0], sizeof(double)),
		     (int *) R_alloc(dims[0], sizeof(int)), &info);
    UNPROTECT(1);
    return ScalarReal(rcond);
}
Ejemplo n.º 5
0
SEXP dgeMatrix_solve(SEXP a)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix"))),
	lu = dgeMatrix_LU_(a, TRUE);
    int *dims = INTEGER(GET_SLOT(lu, Matrix_DimSym)),
	*pivot = INTEGER(GET_SLOT(lu, Matrix_permSym));
    double *x, tmp;
    int	info, lwork = -1;


    if (dims[0] != dims[1]) error(_("Solve requires a square matrix"));
    slot_dup(val, lu, Matrix_xSym);
    x = REAL(GET_SLOT(val, Matrix_xSym));
    slot_dup(val, lu, Matrix_DimSym);
    F77_CALL(dgetri)(dims, x, dims, pivot, &tmp, &lwork, &info);
    lwork = (int) tmp;
    F77_CALL(dgetri)(dims, x, dims, pivot,
		     (double *) R_alloc((size_t) lwork, sizeof(double)),
		     &lwork, &info);
    if (info)
	error(_("Lapack routine dgetri: system is exactly singular"));
    UNPROTECT(1);
    return val;
}
Ejemplo n.º 6
0
SEXP dgeMatrix_LU(SEXP x, SEXP warn_singularity)
{
    dgeMatrix_LU_(x, asLogical(warn_singularity));
}