view yetilab/stream/channels.yeti @ 178:032c4986b6b0

Implement and test matrix concat
author Chris Cannam
date Thu, 02 May 2013 21:58:58 +0100
parents 6ffdf5d4dfcf
children 0c81455270dc
line wrap: on
line source

module yetilab.stream.channels;

vec = load yetilab.block.fvector;
block = load yetilab.block.block;
mat = load yetilab.matrix.matrix;
        
interleaved m = 
   ({ columns, rows } = m.size;
    if rows == 1 then
        m.getRow 0
    else
        v = vec.zeros (columns * rows);
        for [0..rows-1] do row:
            for [0..columns-1] do col:
                v[col * rows + row] := m.getAt row col;
            done;
        done;
        block.block v;
    fi);

deinterleaved channels b =
    if channels == 1 then
        mat.newRowVector b
    else
        rows = (block.length b) / channels;
        vv = array (map \(vec.zeros rows) [0..channels-1]);
        v = block.data b;
        for [0..rows-1] do row:
            for [0..channels-1] do col:
                vv[col][row] := v[channels * row + col];
            done
        done;
        mat.newMatrix (RowMajor ()) (map block.block vv);
    fi;

mixedDown m =
   ({ columns, rows } = m.size;
    v = vec.zeros columns;
    for [0..rows-1] do row:
        for [0..columns-1] do col:
            v[col] := v[col] + m.getAt row col;
        done;
    done;
    block.block v);

mixedDownFromInterleaved channels b =
    if channels == 1 then
        b;
    else
        v = block.data b;
        columns = ((vec.length v) / channels);
        v' = vec.zeros columns;
        for [0..channels-1] do row:
            for [0..columns-1] do col:
                v'[col] := v'[col] + v[col * channels + row];
            done;
        done;
        block.block v';
    fi;

mixedFromInterleavedTo targetChannels channels b = 
    if targetChannels == channels then
        b;
    elif targetChannels == 1 then
        mixedDownFromInterleaved channels b;
    else
        v = block.data b;
        columns = ((vec.length v) / channels);
        v' = vec.zeros (columns * targetChannels);
        for [0..targetChannels-1] do target:
            for [0..columns-1] do col:
                if target < channels then
                    v'[col * targetChannels + target] := v[col * channels + target];
                elif channels == 1 and target == 1 then
                    v'[col * targetChannels + target] := v[col * channels];
                fi
            done
        done;
        block.block v';
    fi;

mixedAndInterleavedTo targetChannels m = 
    if targetChannels == 1 then
        mixedDown m
    else
       (interleaved .
            mat.resizedTo { rows = targetChannels, columns = m.size.columns })
            if m.size.rows == 1 then
               (mat.newMatrix (RowMajor ()) [ m.getRow 0, m.getRow 0 ])
            else
                m
            fi;
    fi;

{
    interleaved, deinterleaved,
    mixedDown, mixedDownFromInterleaved, mixedFromInterleavedTo, mixedAndInterleavedTo
}