示例#1
0
void residu_with_prec_for_chol(SciSparse *A, double x[], double b[], double r[],
                               double *rn, int A_is_upper_triangular, long double wk[])
{
    /*  the same than the previous routine but this one take care of the fact that
     *  when A_is_upper_triangular=1 only the upper triangle part of A is stored */
    int i, j, k, l;
    long double norm2 = 0.0;

    if ( ! A_is_upper_triangular )
    {
        residu_with_prec(A, x, b, r, rn);
    }
    else
    {
        /* A*x-b but only the upper triangle of A is stored */
        for ( i = 0 ; i < A->m ; i++ )
        {
            wk[i] = -(long double) b[i];
        }
        k = 0;
        for ( i = 0 ; i < A->m ; i++ )
        {
            for ( l = 0 ; l < A->mnel[i] ; l++ )
            {
                j = A->icol[k] - 1;
                wk[i] += (long double) A->R[k]  *  (long double) x[j];
                if ( j != i )
                {
                    wk[j] += (long double) A->R[k]  *  (long double) x[i];
                }
                k++;
            }
        }
        for ( i = 0 ; i < A->m ; i++ )
        {
            r[i] = (double) wk[i];
            norm2 += wk[i] * wk[i];
        }
        *rn = (double) sqrt((double)norm2);
    }
    return;
}
示例#2
0
int sci_res_with_prec(char* fname, void* pvApiCtx)
{
    SciErr sciErr;

    int mx = 0, nx = 0, mb = 0, nb = 0, i = 0;

    SciSparse A;
    int mA              = 0; // rows
    int nA              = 0; // cols
    int iNbItem         = 0;
    int* piNbItemRow    = NULL;
    int* piColPos       = NULL;
    double* pdblSpReal  = NULL;
    double* pdblSpImg   = NULL;

    int iComplex = 0;

    int* piAddr1 = NULL;
    int* piAddr2 = NULL;
    int* piAddr3 = NULL;

    double* pdblXR = NULL;
    double* pdblXI = NULL;
    double* pdblBR = NULL;
    double* pdblBI = NULL;
    double* pdblNR = NULL;
    double* pdblNI = NULL;
    double* pdblRR = NULL;
    double* pdblRI = NULL;

    int nbInputArg = nbInputArgument(pvApiCtx);

    /* Check numbers of input/output arguments */
    CheckInputArgument(pvApiCtx, 3, 3);
    CheckOutputArgument(pvApiCtx, 1, 2);

    /* get A the sparse matrix */
    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    if (isVarComplex(pvApiCtx, piAddr1))
    {
        iComplex = 1;
        sciErr = getComplexSparseMatrix(pvApiCtx, piAddr1, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal, &pdblSpImg);
    }
    else
    {
        sciErr = getSparseMatrix(pvApiCtx, piAddr1, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal);
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    // fill struct sparse
    A.m     = mA;
    A.n     = nA;
    A.it    = iComplex;
    A.nel   = iNbItem;
    A.mnel  = piNbItemRow;
    A.icol  = piColPos;
    A.R     = pdblSpReal;
    A.I     = pdblSpImg;

    /* get x */
    sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr2);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    if (isVarComplex(pvApiCtx, piAddr2))
    {
        iComplex = 1;
        sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr2, &mx, &nx, &pdblXR, &pdblXI);
    }
    else
    {
        sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &mx, &nx, &pdblXR);
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* get b */
    sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddr3);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    if (isVarComplex(pvApiCtx, piAddr3))
    {
        iComplex = 1;
        sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr3, &mb, &nb, &pdblBR, &pdblBI);
    }
    else
    {
        sciErr = getMatrixOfDouble(pvApiCtx, piAddr3, &mb, &nb, &pdblBR);
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* check size of inputs */
    if ( nx < 1 || nb != nx || mx != nA || mb != mA )
    {
        Scierror(999, _("%s: Wrong size for input arguments: Same sizes expected.\n"), fname);
        return 1;
    }

    /* Create the matrix as return of the function */
    if (iComplex)
    {
        sciErr = allocComplexMatrixOfDouble(pvApiCtx, 4, mb, nb, &pdblRR, &pdblRI);
    }
    else
    {
        sciErr = allocMatrixOfDouble(pvApiCtx, 4, mb, nb, &pdblRR);
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* Create the matrix as return of the function */
    sciErr = allocMatrixOfDouble(pvApiCtx, 5, 1, nb, &pdblNR);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* perform operations */
    if (iComplex == 0)
    {
        for ( i = 0 ; i < nb ; i++ )
        {
            residu_with_prec(&A, pdblXR + i * mx, pdblBR + i * mb, pdblRR + i * mb, pdblNR + i);
        }
    }
    else
    {
        if (pdblXI == NULL)
        {
            int iSize = mx * nx * sizeof(double);
            pdblXI = (double*)MALLOC(iSize);
            memset(pdblXI, 0x00, iSize);
        }

        if (pdblBI == NULL)
        {
            int iSize = mb * nb * sizeof(double);
            pdblBI = (double*)MALLOC(iSize);
            memset(pdblBI, 0x00, iSize);
        }

        if (pdblSpImg == NULL)
        {
            /* Create the matrix as return of the function */
            int iSize = nb * sizeof(double);
            pdblNI = (double*)MALLOC(iSize);
            memset(pdblNI, 0x00, iSize);

            for ( i = 0 ; i < nb ; i++ )
            {
                residu_with_prec(&A, pdblXR + i * mx, pdblBR + i * mb, pdblRR + i * mb, pdblNR + i);
            }

            for ( i = 0 ; i < nb ; i++ )
            {
                residu_with_prec(&A, pdblXI + i * mx, pdblBI + i * mb, pdblRI + i * mb, pdblNI + i);
            }

            for ( i = 0 ; i < nb ; i++ )
            {
                pdblNR[i] = sqrt(pdblNR[i] * pdblNR[i] + pdblNI[i] * pdblNI[i]);
            }
        }
        else
        {
            for ( i = 0 ; i < nb ; i++ )
            {
                cmplx_residu_with_prec(&A,  pdblXR + i * mx, pdblXI + i * mx,
                                       pdblBR + i * mb, pdblBI + i * mb,
                                       pdblRR + i * mb, pdblRI + i * mb,
                                       pdblNR + i);
            }
        }
    }

    if (isVarComplex(pvApiCtx, piAddr1) == 0)
    {
        FREE(pdblNI);
    }

    if (isVarComplex(pvApiCtx, piAddr2) == 0)
    {
        FREE(pdblXI);
    }

    if (isVarComplex(pvApiCtx, piAddr3) == 0)
    {
        FREE(pdblBI);
    }

    AssignOutputVariable(pvApiCtx, 1) = 4;
    AssignOutputVariable(pvApiCtx, 2) = 5;
    ReturnArguments(pvApiCtx);
    return 0;
}