コード例 #1
0
ファイル: solve_LS_FLP.c プロジェクト: ioid3-games/ioid3-rtcw
static OPUS_INLINE void silk_LDL_FLP(
    silk_float          *A,         /* I/O  Pointer to Symetric Square Matrix                               */
    opus_int            M,          /* I    Size of Matrix                                                  */
    silk_float          *L,         /* I/O  Pointer to Square Upper triangular Matrix                       */
    silk_float          *Dinv       /* I/O  Pointer to vector holding the inverse diagonal elements of D    */
)
{
    opus_int i, j, k, loop_count, err = 1;
    silk_float *ptr1, *ptr2;
    double temp, diag_min_value;
    silk_float v[ MAX_MATRIX_SIZE ] = { 0 }, D[ MAX_MATRIX_SIZE ]; /* temp arrays*/

    silk_assert(M <= MAX_MATRIX_SIZE);

    diag_min_value = FIND_LTP_COND_FAC * 0.5f * (A[ 0 ] + A[ M * M - 1 ]);
    for(loop_count = 0; loop_count < M && err == 1; loop_count++) {
        err = 0;
        for(j = 0; j < M; j++) {
            ptr1 = matrix_adr(L, j, 0, M);
            temp = matrix_ptr(A, j, j, M); /* element in row j column j*/
            for(i = 0; i < j; i++) {
                v[ i ] = ptr1[ i ] * D[ i ];
                temp  -= ptr1[ i ] * v[ i ];
            }
            if(temp < diag_min_value) {
                /* Badly conditioned matrix: add white noise and run again */
                temp = (loop_count + 1) * diag_min_value - temp;
                for(i = 0; i < M; i++) {
                    matrix_ptr(A, i, i, M) += (silk_float)temp;
                }
                err = 1;
                break;
            }
            D[ j ]    = (silk_float)temp;
            Dinv[ j ] = (silk_float)(1.0f / temp);
            matrix_ptr(L, j, j, M) = 1.0f;

            ptr1 = matrix_adr(A, j, 0, M);
            ptr2 = matrix_adr(L, j + 1, 0, M);
            for(i = j + 1; i < M; i++) {
                temp = 0.0;
                for(k = 0; k < j; k++) {
                    temp += ptr2[ k ] * v[ k ];
                }
                matrix_ptr(L, i, j, M) = (silk_float)((ptr1[ i ] - temp) * Dinv[ j ]);
                ptr2 += M; /* go to next column*/
            }
        }
    }
    silk_assert(err == 0);
}
コード例 #2
0
/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
SKP_INLINE void SKP_Silk_LS_SolveLast_FIX(
    const SKP_int32     *L_Q16,     /* I Pointer to Lower Triangular Matrix */
    const SKP_int       M,          /* I Dim of Matrix equation */
    const SKP_int32     *b,         /* I b Vector */
    SKP_int32           *x_Q16      /* O x Vector */  
)
{
    SKP_int i, j;
    const SKP_int32 *ptr32;
    SKP_int32 tmp_32;

    for( i = M - 1; i >= 0; i-- ) {
        ptr32 = matrix_adr( L_Q16, 0, i, M );
        tmp_32 = 0;
        for( j = M - 1; j > i; j-- ) {
            tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ SKP_SMULBB( j, M ) ], x_Q16[ j ] );
        }
        x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 );
    }
}
コード例 #3
0
/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX(
    const SKP_int32     *L_Q16, /* I Pointer to Lower Triangular Matrix */
    SKP_int             M,      /* I Dim of Matrix equation */
    const SKP_int32     *b,     /* I b Vector */
    SKP_int32           *x_Q16  /* O x Vector */  
)
{
    SKP_int i, j;
    const SKP_int32 *ptr32;
    SKP_int32 tmp_32;

    for( i = 0; i < M; i++ ) {
        ptr32 = matrix_adr( L_Q16, i, 0, M );
        tmp_32 = 0;
        for( j = 0; j < i; j++ ) {
            tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] );
        }
        x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 );
    }
}
コード例 #4
0
/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
static inline void silk_LS_SolveLast_FIX(
    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */
    const opus_int      M,          /* I    Dim of Matrix equation                                      */
    const opus_int32    *b,         /* I    b Vector                                                    */
    opus_int32          *x_Q16      /* O    x Vector                                                    */
)
{
    opus_int i, j;
    const opus_int32 *ptr32;
    opus_int32 tmp_32;

    for( i = M - 1; i >= 0; i-- ) {
        ptr32 = matrix_adr( L_Q16, 0, i, M );
        tmp_32 = 0;
        for( j = M - 1; j > i; j-- ) {
            tmp_32 = silk_SMLAWW( tmp_32, ptr32[ silk_SMULBB( j, M ) ], x_Q16[ j ] );
        }
        x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );
    }
}
コード例 #5
0
ファイル: solve_LS_FLP.c プロジェクト: ioid3-games/ioid3-rtcw
static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(
    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */
    opus_int            M,          /* I    Dim of Matrix equation                                          */
    const silk_float    *b,         /* I    b Vector                                                        */
    silk_float          *x          /* O    x Vector                                                        */
)
{
    opus_int   i, j;
    silk_float temp;
    const silk_float *ptr1;

    for(i = 0; i < M; i++) {
        ptr1 =  matrix_adr(L, i, 0, M);
        temp = 0;
        for(j = 0; j < i; j++) {
            temp += ptr1[ j ] * x[ j ];
        }
        temp = b[ i ] - temp;
        x[ i ] = temp;
    }
}
コード例 #6
0
ファイル: solve_LS_FLP.c プロジェクト: ioid3-games/ioid3-rtcw
static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */
    opus_int            M,          /* I    Dim of Matrix equation                                          */
    const silk_float    *b,         /* I    b Vector                                                        */
    silk_float          *x          /* O    x Vector                                                        */
)
{
    opus_int   i, j;
    silk_float temp;
    const silk_float *ptr1;

    for(i = M - 1; i >= 0; i--) {
        ptr1 =  matrix_adr(L, 0, i, M);
        temp = 0;
        for(j = M - 1; j > i ; j--) {
            temp += ptr1[ j * M ] * x[ j ];
        }
        temp = b[ i ] - temp;
        x[ i ] = temp;
    }
}
コード例 #7
0
void SKP_Silk_SolveWithLowerTriangularWdiagOnes_FLP(
    const SKP_float     *L,     /* (I) Pointer to Lower Triangular Matrix */
    SKP_int             M,      /* (I) Dim of Matrix equation */
    const SKP_float     *b,     /* (I) b Vector */
    SKP_float           *x      /* (O) x Vector */  
)
{
    SKP_int   i, j;
    SKP_float temp;
    const SKP_float *ptr1;
    
    for( i = 0; i < M; i++ ) {
        ptr1 =  matrix_adr( L, i, 0, M );
        temp = 0;
        for( j = 0; j < i; j++ ) {
            temp += ptr1[ j ] * x[ j ];
        }
        temp = b[ i ] - temp;
        x[ i ] = temp;
    }
}
コード例 #8
0
void SKP_Silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
    const SKP_float     *L,     /* (I) Pointer to Lower Triangular Matrix */
    SKP_int             M,      /* (I) Dim of Matrix equation */
    const SKP_float     *b,     /* (I) b Vector */
    SKP_float           *x      /* (O) x Vector */  
)
{
    SKP_int   i, j;
    SKP_float temp;
    const SKP_float *ptr1;
    
    for( i = M - 1; i >= 0; i-- ) {
        ptr1 =  matrix_adr( L, 0, i, M );
        temp = 0;
        for( j = M - 1; j > i ; j-- ) {
            temp += ptr1[ j * M ] * x[ j ];
        }
        temp = b[ i ] - temp;
        x[ i ] = temp;      
    }
}
コード例 #9
0
SKP_INLINE void SKP_Silk_LDL_factorize_FIX(
    SKP_int32           *A,         /* I   Pointer to Symetric Square Matrix */
    SKP_int             M,          /* I   Size of Matrix */
    SKP_int32           *L_Q16,     /* I/O Pointer to Square Upper triangular Matrix */
    inv_D_t             *inv_D      /* I/O Pointer to vector holding inverted diagonal elements of D */
)
{
    SKP_int   i, j, k, status, loop_count;
    const SKP_int32 *ptr1, *ptr2;
    SKP_int32 diag_min_value, tmp_32, err;
    SKP_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ];
    SKP_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48;

    SKP_assert( M <= MAX_MATRIX_SIZE );

    status = 1;
    diag_min_value = SKP_max_32( SKP_SMMUL( SKP_ADD_SAT32( A[ 0 ], A[ SKP_SMULBB( M, M ) - 1 ] ), SKP_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 );
    for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) {
        status = 0;
        for( j = 0; j < M; j++ ) {
            ptr1 = matrix_adr( L_Q16, j, 0, M );
            tmp_32 = 0;
            for( i = 0; i < j; i++ ) {
                v_Q0[ i ] = SKP_SMULWW(         D_Q0[ i ], ptr1[ i ] ); /* Q0 */
                tmp_32    = SKP_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */
            }
            tmp_32 = SKP_SUB32( matrix_ptr( A, j, j, M ), tmp_32 );

            if( tmp_32 < diag_min_value ) {
                tmp_32 = SKP_SUB32( SKP_SMULBB( loop_count + 1, diag_min_value ), tmp_32 );
                /* Matrix not positive semi-definite, or ill conditioned */
                for( i = 0; i < M; i++ ) {
                    matrix_ptr( A, i, i, M ) = SKP_ADD32( matrix_ptr( A, i, i, M ), tmp_32 );
                }
                status = 1;
                break;
            }
            D_Q0[ j ] = tmp_32;                         /* always < max(Correlation) */
        
            /* two-step division */
            one_div_diag_Q36 = SKP_INVERSE32_varQ( tmp_32, 36 );                    /* Q36 */
            one_div_diag_Q40 = SKP_LSHIFT( one_div_diag_Q36, 4 );                   /* Q40 */
            err = SKP_SUB32( 1 << 24, SKP_SMULWW( tmp_32, one_div_diag_Q40 ) );     /* Q24 */
            one_div_diag_Q48 = SKP_SMULWW( err, one_div_diag_Q40 );                 /* Q48 */

            /* Save 1/Ds */
            inv_D[ j ].Q36_part = one_div_diag_Q36;
            inv_D[ j ].Q48_part = one_div_diag_Q48;

            matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */
            ptr1 = matrix_adr( A, j, 0, M );
            ptr2 = matrix_adr( L_Q16, j + 1, 0, M );
            for( i = j + 1; i < M; i++ ) { 
                tmp_32 = 0;
                for( k = 0; k < j; k++ ) {
                    tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */
                }
                tmp_32 = SKP_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */

                /* tmp_32 / D_Q0[j] : Divide to Q16 */
                matrix_ptr( L_Q16, i, j, M ) = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ),
                    SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );

                /* go to next column */
                ptr2 += M; 
            }
        }
    }

    SKP_assert( status == 0 );
}