# Linearizing a 2D Array/Matrix

• 03-02-2009, 06:42 PM
dalangley
Linearizing a 2D Array/Matrix
Alright, I need to write two methods, the first of which linearizes a matrix, such as 4x6. I need to convert it into 1 x (4*6). So the number of rows becomes one and the columns are the product of the dimensions of the matrix.

So a 3x3 would revert into a 1x9 where all the elements in each index were in their own column.

| 1 1 1 |
| 2 2 2 |
| 3 3 3 |

would need to convert to:

| 1 1 1 2 2 2 3 3 3 |

This is what I have so far for the linearize method.

Code:

```public Matrix linearize()   {       Matrix result = new Matrix();     int rows    = 1;     int columns  = this.getColumns() * this.getRows();     result.theArray = new int[rows][columns];     for( int r = 0; r < result.getRows(); r++ )             for( int c = 0; c < result.getColumns(); c++ )             {               result.theArray[r][c] = theArray[c].length;             }             return result;   }```
I have got the conversion to a 1xN matrix down, but i dont know how to fill the columns with the data which are in each index. I think this part needs to be changed,
Code:

`result.theArray[r][c] = theArray[c].length;`
, but to what?

Thanks for any help.
• 03-02-2009, 06:49 PM
Nicholas Jordan
Several approaches are available, keep going with what you have. Start with a dual approach of having a list or something from the Collections and do append then toArray and cast to the array type you need.

The other, which is where you are going, is doen by allocation a new array as int[] anArray = new int [ ( numRow * numColumn) ]; then just tediously work the loop logic until you get something that lists correctly on an array walk.

Easy to miss for several test cycles, then if falls like rain.

The entire information empire is rooted in which way the loop runs, head first or feet first.

Don't buy any books to solve this, just work it till it works.

Be sure to write some test harness.
• 03-02-2009, 07:02 PM
dalangley
Forgive me for sounding rather green, (while I am indeed green), as I have only been in the Java world for about 8 months now. I do know that I cannot call to any other methods outside the class such as .append (while ive seen them myself). The approach that I am currently taking is the one ill be using, I just cant work around that last bit of code, where i need to fill the array.

Code:

```Matrix C(5, 2):         |  -3    0  |         |  1    3  |         |  -1    0  |         |  4  -3  |         |  0    1  |```
^ That is the matrix that will be linearized.
And this method approach so far has gotten me:
Code:

```Matrix V(1, 10):         |  -3    0    0    0    0    0    0    0    0    0  |```
Current method structure:

Code:

```public Matrix linearize()   {       Matrix result = new Matrix();     int rows    = 1;     int columns  = this.getColumns() * this.getRows();     result.theArray = new int[rows][columns];     [COLOR="blue"]for( int r = 0; r < result.getRows(); r++ )             for( int c = 0; c < this.getColumns(); c++ )[/COLOR]             {               [COLOR="Blue"]result.theArray[r][c] = this.theArray[r][c];[/COLOR]             }             return result;   }```
So why is it only filling one of the indexs? (-3)

Where is the fault in my loop, as I assume its there.

Due by midnight CST, this is the last step, Would appreciate any solutions.

UPDATE: Still very much stuck.
• 03-02-2009, 07:55 PM
dalangley
Any help at all? Google seems to be useless as I cant find anything on this particular problem I am having.
• 03-02-2009, 08:02 PM
angryboy
you will need to so something similar to this:
Code:

```    int k = -1;     for(int j=0; j<matrix.length; ++j){       for(int i=0; i<matrix[j].length; ++i){         flat[++k] = matrix[j][i];       }     }```
• 03-02-2009, 08:19 PM
dalangley
Code:

```public Matrix linearize()   {     int data  = this.getColumns() * this.getRows();     int[] result = new int[data];     int k = -1;     for( int j = 0; j < this.theArray.length; j++ )             for( int i = 0; i < this.theArray[j].length; i++ )             {               result[++k] = this.theArray[j][i];             }             return result;   }```
Ok that is what i have rewritten, and its throwing an error because it needs to be of the class type (Matrix). But when i changed the method type to Matrix as seen above the it throws :

Code:

```Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - incompatible types found  : int[] required: Matrix```

What do i need to change to get the result to get through? Do i have the wrong type somewhere?
• 03-02-2009, 08:32 PM
angryboy
the error msg tells all.

change return type from Matrix to int[]. or,
change result in loop to:
result.theArray[r][++k] =
• 03-02-2009, 11:02 PM
dalangley
Code:

```public Matrix linearize()   {     int data  = this.getColumns() * this.getRows();     int[] result = new int[data];     int k = -1;     for( int j = 0; j < this.theArray.length; j++ )             for( int i = 0; i < this.theArray[j].length; i++ )             {               result[++k] = this.theArray[j][i];             }         return result;   }```
This also throws an error in its current structure above. To give an idea of why it might be doing this the method is invoked through a 2D array,such as:

A.linearize();

Where A is the 2D array or Matrix. So A is a Matrix object being passed into a method that needs to return a 1D Array or Flat Array. I am following your logic but the code won't work in its current state. I believe it is a matter of the method type, but either way I switch it it throws the error. If I make it Matrix type as seen above, the 1D array "result" is not able to be a return type. This is rather frustrating, and I am sure its something simple. Any ideas? Or a reference to a method elsewhere?
• 03-02-2009, 11:11 PM
dalangley
Code:

``` public Matrix linearize()   {     Matrix result = new Matrix();     int rows    = 1;     int columns  = this.getColumns() * this.getRows();     result.theArray = new int[rows][columns];     for( int r = 0; r < result.getRows(); r++ )             for( int c = 0; c < this.getColumns(); c++ )             {               result.theArray[r][c] = this.theArray[r][c];             }         return result;   }```
I went back to this method body for multiple reasons, the first being that it throws no error whatsoever, but doesnt fill the flat array completely. I start with this Matrix:
Code:

```Matrix C(5, 2):         |  -3    0  |         |  1    3  |         |  -1    0  |         |  4  -3  |         |  0    1  |```

and it linearizes yes, but it doesn't completely fill it:

Code:

```Matrix V(1, 10):         |  -3    0    0    0    0    0    0    0    0    0  |```

So as you can see it is doing the first 2 indexes but not the rest, where in the for loop does this need to change? or is it in the result?
• 03-02-2009, 11:32 PM
dalangley
Code:

```for( int r = 0; r < result.getRows(); r++ )             [COLOR="Blue"]for( int c = 0; c < this.getColumns(); c++ )[/COLOR]             {               result.theArray[r][c] = this.theArray[r][c];             }         return result;```
This is the culprit. You see I am stuck at this.getColumns() which will only give the first two indexes because the number of columns in the original 2D array (C) is 2. So what do I use as the test in the for loop?
• 03-02-2009, 11:52 PM
dalangley
Any ideas? This has had me stumped for hours now, Im hitting a brick wall on what I need to change in the for loop to make it iterate through ALL of the data in this.theArray .
• 03-03-2009, 12:42 AM
pbrockway2
Code:

```for( int r = 0; r < result.getRows(); r++ ) {     for( int c = 0; c < this.getColumns(); c++ )     {         result.theArray[r][c] = this.theArray[r][c];     } } return result;```
There's something strange here. result.theArray has lots of columns, right? Because it's a row vector.

But in your code you assign to it with result.theArray[r][c] where c<this.getColumns().

Edit...

On rereading the thread, I see that you have already been given code that iterates through the source matrix. (It uses the number of rows and columns in the source matrix to do so).

Of the code you have now (rather than that suggested by replies #5 and #7) you say:
Quote:

I went back to this method body for multiple reasons, the first being that it throws no error whatsoever
If you'll pardon me this is a bit wrong headed. They aren't errors; they're messages. That's not a nitpick, compiler messages are helpful and they're not meant to be got around. They should be read, understood and responded to.
• 03-03-2009, 01:07 AM
angryboy
what i meant in reply #7 is:
going back to your original code...
Code:

```public Matrix linearize()   {       Matrix result = new Matrix();     int rows    = 1;     int columns  = this.getColumns() * this.getRows();     result.theArray = new int[rows][columns]; [B]    int k = -1;     for( int j = 0; j < this.theArray.length; j++ )             for( int i = 0; i < this.theArray[j].length; i++ )             {               result.theArray[0][++k] = theArray[j][i].length;             }[/B]             return result;   }```
how could you return a 1D array when it is expecting a 2D array.
that was what the error msg was complaining about.
• 03-03-2009, 01:26 AM
dalangley
Code:

```public Matrix linearize()   {     Matrix result = new Matrix();     int rows    = 1;     int columns  = this.getColumns() * this.getRows();     result.theArray = new int[rows][columns];       for( int r = 0; r < result.getRows(); r++ )             for( int c = 0; c < this.getColumns(); c++ )             {               result.theArray[r][c] += this.theArray[r][c];             }         return result;   }```
This format is working correctly, It doesnt throw any messages or erroes whatsoever. I just need to rework the loop, which is my latest problem, it only runs through to the amount of rows the original 2d array had and i need it to include every number in the new array also. not just the first two indexes. So help me with the increments in the for loop:

Code:

```    for( int r = 0; r < result.getRows(); r++ )             for( int c = 0; c < this.getColumns(); c++ )```
What do i need to change in the test on either r, being rows, and c being columns?