# Removing zeros from a matrix

I am trying to define a matrix with non-zero values from a data array that contains zero values.

Below is my attempt so far and have hit a block. When I "Regenerate sample matrix", my code is wrong. Obviously I am trying to access elements outside the range here.

If someone can take a look and make some suggestions that would be great.

``````// Sample array
sample = ROC( C, 1 );

// Generate sample matrix
sampleMatrix = Matrix( 1, BarCount, Null );
sampleMatrixSize = MxGetSize( sampleMatrix, 1 );
for( i = 0; i < sampleMatrixSize; i++ ) {
sampleMatrix[i] = sample[i];
}

// Redefine sample matrix removing zeros
// Non-zero matrix size
sampleMatrixSizeNz = 0;
for( i = 0; i < BarCount; i++ ) {
if( sampleMatrix[i] != 0 ) sampleMatrixSizeNz++;
}

// Regenerate sample matrix
sampleMatrixNz = Matrix( 1, sampleMatrixSizeNz, Null );
for( i = 0; i < sampleMatrixSize; i++ ) {
if( sampleMatrix[i] != 0 ) {
sampleMatrixNz[i] = sampleMatrix[i];
}
}
``````

The subscript of your adjusted matrix (which can have different size than your first one) in your last loop can not to be "i" but has to be one that is incremented when condition is true.

``````// Sample array
sample = ROC( C, 1 );

// Generate sample matrix
sampleMatrix = Matrix( 1, BarCount, Null );
sampleMatrixSize = MxGetSize( sampleMatrix, 1 );

for( i = 0; i < sampleMatrixSize; i++ ) {
sampleMatrix[i] = sample[i];
}

// Redefine sample matrix removing zeros
// Non-zero matrix size
sampleMatrixSizeNz = 0;
for( i = 0; i < BarCount; i++ ) {
if( sampleMatrix[i] != 0 ) sampleMatrixSizeNz++;
//else printf( "\nzero: %g", sampleMatrix[i] );
}

// Regenerate sample matrix
sampleMatrixNz = Matrix( 1, sampleMatrixSizeNz, Null );

n = 0;
for( i = 0; i < sampleMatrixSize; i++ ) {
if( sampleMatrix[i] != 0 ) {
sampleMatrixNz[n++] = sampleMatrix[i];
}
}

printf( "\nsize1: %g\n", MxGetSize( sampleMatrix, 1 ) );
//printf( MxToString(sampleMatrix) );
printf( "\nsize2: %g", MxGetSize( sampleMatrixNz, 1) );
//printf( MxToString(sampleMatrixNz) );
``````
2 Likes

Thank you for that. Works a treat and I learned something new.

BTW, there is not any single loop required in order to achieve what you are trying to get done. Not any.

Just take a look at your first loop, for example.

The same thing can be achieved using MxSetBlock().

``````// Sample array
sample = ROC( C, 1 );

// Generate sample matrix
sampleMatrix = Matrix( 1, colnum = BarCount, Null );
sampleMatrix = MxSetBlock(sampleMatrix, 0, 0, 0, colnum-1, sample);

MxToString( sampleMatrix );
``````

Same applies to the rest of your code. All can be done without any looping.
So as for sampleMatrixNz... just create a sparsed array and again use MxSetBlock. 4 to 5 lines of code but not more.

1 Like

I'm not fully understanding how I would use MxSetBlock for my non-zero matrix. As I see it, the sample input (sparse array) contains zeros and would therefore not be of an equal matrix size to block set it into a new matrix.

Don't I need to iterate through my original matrix to find the zeros and skip them using a loop?

No, you do not iterate at all. Not a single time in your case. Just trust me when I am saying something. I am not telling things out of the blue but doing so as a result of having a clue (you see, I am a poet in addition).

Anyway, just take a look at full function list of AmiBroker manual. Together with Matrix(), MxSetBlock() and function for sparse array you would need just two additional functions (think before what you would need to do). That's it. Maximum 4 lines.