How to dynamically allocate space for an "incomplete" matrix?

Hello. I'm having an issue with the function below. It is a function that takes as argument a dynamically allocated diagonal matrix, along with its respective number of rows and columns (where x == y always, since it's a diagonal matrix). With these arguments, what the function should do is to dynamically allocate the space to receive a new matrix that contains only part of the diagonal matrix, like in these examples:

Example 1:
Matrix:
1 0 0
0 1 0
0 0 1

New generated matrix:
1
0 1
0 0 1

Example 2:
Matrix:
2 3
3 2

New generated matrix:
2
3 2

Example 3:
Matrix:
2 2 2 2
2 2 2 2
2 2 2 2
2 2 2 2

New generated matrix:
2
2 2
2 2 2
2 2 2 2

The problem is that somehow the new matrix is receiving all values from the old matrix and not only the ones I want (the first half of the diagonal). Any tips?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int ** diagonal(int ** matrix, int x, int y)
{
	// Allocating the number of rows...
	int ** reduced_matrix = new int* [x];
	int aux = 1; 

	// Allocating the number of columns 
	for (int i=0;i<x;i++)
	{
		reduced_matrix[i] = new int [aux];
		aux++; // The number of columns increases after every row
	}

	// The reduced matrix gets its values
	for (int i=0;i<x;i++)
		for (int j=0;j<aux;j++)
			reduced_matrix[i][j] = matrix[i][j];

	// The problem: I should not be able to show all these values below, only the ones I have alocated.
		for (int i=0;i<x;i++)
		{
			for (int j=0;j<y;j++)
			{
				cout << reduced_matrix[i][j] << " ";
			}
		cout << endl;
		}

		return reduced_matrix;
}
its going to depend on how you want to do it. I found it faster, though it wastes memory, to allocate and pass the whole thing for upper and lowers, and pass a special 1-d vector for diagonal onlys.

you can try the sparse matrix stuff, where you store the value and its location together, everything else is assumed zero. But you still have to unwind it back into the normal format to use your functions, or write special versions of every function. I did not care for this; the only nod I made to sparse was a multiply that could zero out the sum of products where appropriate for speed, but we didn't have a lot of sparse or factoring.

you can make your data structures weird .. define a matrix as a vector of vectors and each of those can have a different length. This can be done with 1 version of the functions as you use the built in lengths, but you have to watch out for performance issues on big matrices as vectors and 2-d setups have gotchas.

I highly recommend if you are not running the system out of memory, to just zero out the unused locations. Or zero the whole thing first with a memset or std fill call, then populate it. I also highly recommend collapsing all your matrix to 1-d arrays, and accessing as if 2-d. It simplifies multiple things as you develop linear algebra routines.


If x is the same as y it's called a square matrix, not a diagonal one. Your final matrix is lower triangular, not "half a diagonal".

You don't need a variable aux: just allocate i+1 columns on line 10.

In your nested loops, starting on lines 15 and 16, aux will have the constant value x+1. This isn't pretty, as you will be attempting to write far beyond the allocated array bounds for most columns.

@lastchance

But every diagonal matrix is ​​a square matrix, but not every square matrix is ​​a diagonal matrix, right?
By the way, I think I've been able to solve the problem with your tip. From what I tested, when you try to access an element in a column that was not allocated, the value shown will always be 0. If you try to access the value on an unallocated row, the compiler will say there is a segmentation error.
But every diagonal matrix is ​​a square matrix, but not every square matrix is ​​a diagonal matrix, right?

That is correct. A diagonal matrix only has non-zero entries on the diagonal. You can use a shorthand (in mathematics, not c++) diag( a, b, c ... ). The 3x3 identity matrix is diag(1,1,1).

when you try to access an element in a column that was not allocated, the value shown will always be 0.

If you try to access an element beyond the bounds of an array, allocated or not, you would get whatever happens to be in that memory location - it won't have any relationship to your array, certainly can't be guaranteed to be 0 and may or may not crash the program. Best not to do it!


@jonnin gave some useful advice and I note that when I'm programming at work (for CFD - computational fluid dynamics) I rarely use multi-dimensional arrays - by the time you have multi-block 3-d arrays that leads to 4 indices. I find it easier, quicker, safer, faster to write to file and easier to parallelise if I collapse them to 1-d arrays, with translation functions to take me from the multi-d indices to the 1-d ones and vice versa.
Topic archived. No new replies allowed.