Exemple #1
0
MAT * block_diagonal_MAT( const MAT mat, const int n){
    validate(NULL!=mat,NULL);
    validate(mat->ncol==mat->nrow,NULL);    // Ensure symmetry
    const int nelts = mat->ncol / n;        // Number of blocks on diagonal
    validate((mat->ncol % n)==0,NULL);      // Is parameter valid?
    
    // Create memory
    MAT * mats = calloc(nelts,sizeof(*mats));
    if(NULL==mats){ goto cleanup; }
    for ( int i=0 ; i<nelts ; i++){
        mats[i] = new_MAT(n,n);
        if(NULL==mats[i]){ goto cleanup;}
    }
    // Copy into diagonals
    for ( int i=0 ; i<nelts ; i++){
        for ( int col=0 ; col<n ; col++){
            const int oldcol = i*n+col;
            for ( int row=0 ; row<n ; row++){
                const int oldrow = i*n+row;
                mats[i]->x[col*n+row] = mat->x[oldcol*mat->nrow+oldrow];
            }
        }
    }
    return mats;
    
cleanup:
    if(NULL!=mats){
        for ( int i=0 ; i<nelts ; i++){
            free_MAT(mats[i]);
        }
    }
    xfree(mats);
    return NULL;
}
Exemple #2
0
/**
 * Process intensities.
 * ip = Minv %*% (Intensities-N) %*% Pinv
 *   - Uses identity: Vec(ip) = ( Pinv^t kronecker Minv) Vec(Intensities-N)
 *   - Storing Intensities-N as an intermediate saved < 3%
 *   - Calculating ip^t rather than ip (pcol loop is over minor index) made no difference
 *   - Using Pinv rather than Pinv^t makes little appreciable difference
 */
MAT process_intensities(const MAT intensities,
                        const MAT Minv_t, const MAT Pinv_t, const MAT N, MAT ip) {

    validate(NULL != intensities, NULL);
    validate(NULL != Minv_t, NULL);
    validate(NULL != Pinv_t, NULL);
    validate(NULL != N, NULL);

    const uint_fast32_t ncycle = Pinv_t->nrow;
    if (NULL==ip) {
        ip = new_MAT(NBASE, ncycle);
        validate(NULL != ip, NULL);
    }
    memset(ip->x, 0, ip->nrow * ip->ncol * sizeof(real_t));

    // pre-calculate I - N, especially as I now integer
    real_t *tmp = calloc(NBASE * ncycle, sizeof(real_t));
    if (NULL==tmp) {
        goto cleanup;
    }

    for (uint_fast32_t i = 0; i < (NBASE * ncycle); i++) {
        tmp[i] = intensities->xint[i] - N->x[i];
    }

    for (uint_fast32_t icol = 0; icol < ncycle; icol++) {    // Columns of Intensity
        for (uint_fast32_t base = 0; base < NBASE; base++) { // Bases (rows of Minv, cols of Minv_t)
            real_t dp = 0;
            for (uint_fast32_t chan = 0; chan < NBASE; chan++) {  // Channels
                dp += Minv_t->x[base * NBASE + chan] * tmp[icol * NBASE + chan];
            }
            for (uint_fast32_t pcol = 0; pcol < ncycle; pcol++) { // Columns of ip
                ip->x[pcol * NBASE + base] += Pinv_t->x[icol * ncycle + pcol] * dp;
            }
        }
    }

    free(tmp);
    return ip;

cleanup:
    free_MAT(ip);
    return NULL;

}