/*************************************************************************
Problem testing
*************************************************************************/
static void testproblem(const ap::complex_2d_array& a, int n)
{
    int i;
    int j;
    ap::complex_2d_array b;
    ap::complex_2d_array c;
    ap::integer_1d_array pivots;
    ap::complex v1;
    ap::complex v2;
    ap::complex ve;

    b.setbounds(1, n, 1, n);
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            b(i,j) = a(i-1,j-1);
        }
    }
    ve = dettriangle(b, n);
    v1 = cmatrixdet(a, n);
    makeacopy(a, n, n, c);
    cmatrixlu(c, n, n, pivots);
    v2 = cmatrixludet(c, pivots, n);
    if( ve!=0 )
    {
        deterrors = deterrors||ap::abscomplex((v1-ve)/ap::maxreal(ap::abscomplex(ve), double(1)))>1.0E-9;
        deterrors = deterrors||ap::abscomplex((v1-ve)/ap::maxreal(ap::abscomplex(ve), double(1)))>1.0E-9;
    }
    else
    {
        deterrors = deterrors||v1!=ve;
        deterrors = deterrors||v2!=ve;
    }
}
Exemple #2
0
/*************************************************************************
Inversion of a general complex matrix.

Input parameters:
    A   -   matrix. Array whose indexes range within [0..N-1, 0..N-1].
    N   -   size of matrix A.

Output parameters:
    A   -   inverse of matrix A.
            Array whose indexes range within [0..N-1, 0..N-1].

Result:
    True, if the matrix is not singular.
    False, if the matrix is singular.

  -- ALGLIB --
     Copyright 2005 by Bochkanov Sergey
*************************************************************************/
bool cmatrixinverse(ap::complex_2d_array& a, int n)
{
    bool result;
    ap::integer_1d_array pivots;

    cmatrixlu(a, n, n, pivots);
    result = cmatrixluinverse(a, pivots, n);
    return result;
}
Exemple #3
0
/*************************************************************************
Solving a system of linear equations.

The algorithm solves a system of linear equations by using the
LU decomposition. The algorithm solves systems with a square matrix only.

Input parameters:
    A   -   system matrix.
            Array whose indexes range within [0..N-1, 0..N-1].
    B   -   right side of a system.
            Array whose indexes range within [0..N-1].
    N   -   size of matrix A.

Output parameters:
    X   -   solution of a system.
            Array whose index ranges within [0..N-1].

Result:
    True, if the matrix is not singular.
    False, if the matrix is singular. In this case, X doesn't contain a
solution.

  -- ALGLIB --
     Copyright 2005-2008 by Bochkanov Sergey
*************************************************************************/
bool cmatrixsolve(ap::complex_2d_array a,
                  ap::complex_1d_array b,
                  int n,
                  ap::complex_1d_array& x)
{
    bool result;
    ap::integer_1d_array pivots;
    int i;

    cmatrixlu(a, n, n, pivots);
    result = cmatrixlusolve(a, pivots, b, n, x);
    return result;
}
/*************************************************************************
Problem testing
*************************************************************************/
static void testproblem(const ap::complex_2d_array& a, int n)
{
    ap::complex_2d_array b;
    ap::complex_2d_array blu;
    ap::complex_2d_array t1;
    ap::integer_1d_array p;
    int i;
    int j;
    ap::complex v;

    
    //
    // Decomposition
    //
    makeacopy(a, n, n, b);
    cmatrixinverse(b, n);
    makeacopy(a, n, n, blu);
    cmatrixlu(blu, n, n, p);
    cmatrixluinverse(blu, p, n);
    
    //
    // Test
    //
    t1.setbounds(0, n-1, 0, n-1);
    internalmatrixmatrixmultiply(a, 0, n-1, 0, n-1, false, b, 0, n-1, 0, n-1, false, t1, 0, n-1, 0, n-1);
    for(i = 0; i <= n-1; i++)
    {
        for(j = 0; j <= n-1; j++)
        {
            v = t1(i,j);
            if( i==j )
            {
                v = v-1;
            }
            inverrors = inverrors||ap::abscomplex(v)>threshold;
        }
    }
    internalmatrixmatrixmultiply(a, 0, n-1, 0, n-1, false, blu, 0, n-1, 0, n-1, false, t1, 0, n-1, 0, n-1);
    for(i = 0; i <= n-1; i++)
    {
        for(j = 0; j <= n-1; j++)
        {
            v = t1(i,j);
            if( i==j )
            {
                v = v-1;
            }
            inverrors = inverrors||ap::abscomplex(v)>threshold;
        }
    }
}
Exemple #5
0
/*************************************************************************
Returns True for successful test, False - for failed test
*************************************************************************/
static bool testcmatrixrcond(int maxn, int passcount)
{
    bool result;
    ap::complex_2d_array a;
    ap::complex_2d_array lua;
    ap::integer_1d_array p;
    int n;
    int i;
    int j;
    int pass;
    bool err50;
    bool err90;
    bool errless;
    bool errspec;
    double erc1;
    double ercinf;
    ap::real_1d_array q50;
    ap::real_1d_array q90;
    double v;

    q50.setbounds(0, 3);
    q90.setbounds(0, 3);
    err50 = false;
    err90 = false;
    errless = false;
    errspec = false;
    
    //
    // process
    //
    for(n = 1; n <= maxn; n++)
    {
        
        //
        // special test for zero matrix
        //
        cmatrixgenzero(a, n);
        cmatrixmakeacopy(a, n, n, lua);
        cmatrixlu(lua, n, n, p);
        errspec = errspec||ap::fp_neq(cmatrixrcond1(a, n),0);
        errspec = errspec||ap::fp_neq(cmatrixrcondinf(a, n),0);
        errspec = errspec||ap::fp_neq(cmatrixlurcond1(lua, n),0);
        errspec = errspec||ap::fp_neq(cmatrixlurcondinf(lua, n),0);
        
        //
        // general test
        //
        a.setbounds(0, n-1, 0, n-1);
        for(i = 0; i <= 3; i++)
        {
            q50(i) = 0;
            q90(i) = 0;
        }
        for(pass = 1; pass <= passcount; pass++)
        {
            cmatrixrndcond(n, exp(ap::randomreal()*log(double(1000))), a);
            cmatrixmakeacopy(a, n, n, lua);
            cmatrixlu(lua, n, n, p);
            cmatrixrefrcond(a, n, erc1, ercinf);
            
            //
            // 1-norm, normal
            //
            v = 1/cmatrixrcond1(a, n);
            if( ap::fp_greater_eq(v,threshold50*erc1) )
            {
                q50(0) = q50(0)+double(1)/double(passcount);
            }
            if( ap::fp_greater_eq(v,threshold90*erc1) )
            {
                q90(0) = q90(0)+double(1)/double(passcount);
            }
            errless = errless||ap::fp_greater(v,erc1*1.001);
            
            //
            // 1-norm, LU
            //
            v = 1/cmatrixlurcond1(lua, n);
            if( ap::fp_greater_eq(v,threshold50*erc1) )
            {
                q50(1) = q50(1)+double(1)/double(passcount);
            }
            if( ap::fp_greater_eq(v,threshold90*erc1) )
            {
                q90(1) = q90(1)+double(1)/double(passcount);
            }
            errless = errless||ap::fp_greater(v,erc1*1.001);
            
            //
            // Inf-norm, normal
            //
            v = 1/cmatrixrcondinf(a, n);
            if( ap::fp_greater_eq(v,threshold50*ercinf) )
            {
                q50(2) = q50(2)+double(1)/double(passcount);
            }
            if( ap::fp_greater_eq(v,threshold90*ercinf) )
            {
                q90(2) = q90(2)+double(1)/double(passcount);
            }
            errless = errless||ap::fp_greater(v,ercinf*1.001);
            
            //
            // Inf-norm, LU
            //
            v = 1/cmatrixlurcondinf(lua, n);
            if( ap::fp_greater_eq(v,threshold50*ercinf) )
            {
                q50(3) = q50(3)+double(1)/double(passcount);
            }
            if( ap::fp_greater_eq(v,threshold90*ercinf) )
            {
                q90(3) = q90(3)+double(1)/double(passcount);
            }
            errless = errless||ap::fp_greater(v,ercinf*1.001);
        }
        for(i = 0; i <= 3; i++)
        {
            err50 = err50||ap::fp_less(q50(i),0.50);
            err90 = err90||ap::fp_less(q90(i),0.90);
        }
        
        //
        // degenerate matrix test
        //
        if( n>=3 )
        {
            a.setlength(n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    a(i,j) = 0.0;
                }
            }
            a(0,0) = 1;
            a(n-1,n-1) = 1;
            errspec = errspec||ap::fp_neq(cmatrixrcond1(a, n),0);
            errspec = errspec||ap::fp_neq(cmatrixrcondinf(a, n),0);
            errspec = errspec||ap::fp_neq(cmatrixlurcond1(a, n),0);
            errspec = errspec||ap::fp_neq(cmatrixlurcondinf(a, n),0);
        }
        
        //
        // near-degenerate matrix test
        //
        if( n>=2 )
        {
            a.setlength(n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    a(i,j) = 0.0;
                }
            }
            for(i = 0; i <= n-1; i++)
            {
                a(i,i) = 1;
            }
            i = ap::randominteger(n);
            a(i,i) = 0.1*ap::maxrealnumber;
            errspec = errspec||ap::fp_neq(cmatrixrcond1(a, n),0);
            errspec = errspec||ap::fp_neq(cmatrixrcondinf(a, n),0);
            errspec = errspec||ap::fp_neq(cmatrixlurcond1(a, n),0);
            errspec = errspec||ap::fp_neq(cmatrixlurcondinf(a, n),0);
        }
    }
    
    //
    // report
    //
    result = !(err50||err90||errless||errspec);
    return result;
}