How to represent a diagonal elements of a matrix into 1-row vector

Hi, I would like to extract a diagonal element from matrix Z and put it in the form of 1-row vector in c++. I used this code and it works in my Visual Studio. Unfortunately, it is not understandable for the hardware platform(FPGA).
1
2
3
4
5
6
7
8
9
10
11
 
//Form a vector extracted from the main diagonal of W
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if ((i >= 0) && (j <= n) && (j - i == 0)) {
				vecD.push_back(W[i][j]);
			}
		}
	}


Therefore, I need some help to represent this into 1-row vector using low-level c++ code. Thank you.
It often helps to get out a piece of paper and a pencil to understand what it is you are trying to accomplish. If I understand you correctly, you are attempting to make the following extraction/transformation:
    0   1   2
  ┌───┬───┬───┐
0 │ a │   │   │
  ├───┼───┼───┤
1 │   │ b │   │
  ├───┼───┼───┤
2 │   │   │ c │
  └───┴───┴───┘
    ↓   ↓   ↓
  ┌───┬───┬───┐
  │ a │ b │ c │
  └───┴───┴───┘

Notice that the only indices you wish to access in the matrix are x==y. This makes for a single-loop solution:

1
2
3
4
5
6
7
// extract the diagonal of 'matrix' into a 'result' vector
//
void extract_diagonal( double matrix[ SIZE ][ SIZE ], double result[ SIZE ] )
{
  for (int n = 0; n < SIZE; n++)
    result[ n ] = matrix[ n ][ n ];
}

Use it easily:

1
2
3
4
5
6
7
8
9
10
int m[ SIZE ][ SIZE ];
...

int d[ SIZE ];
extract_diagonal( m, d );

std::cout << "The diagonal is:";
for (int n = 0; n < SIZE; n++)
  std::cout << " " << d[ n ];
std::cout << "\n";


The code I wrote for you is designed to be simple. I avoided using templates or other fancy stuff. Notice that the SIZE is (apparently) some kind of global constant. Also note that the element type of the matrix is fixed at a 'double'. Were I to write it as a templated function, it would be:

1
2
3
4
5
6
template <typename T, std::size_t SIZE>
void extract_diagonal( T matrix[ SIZE ][ SIZE ], T result[ SIZE ] )
{
  for (std::size_t n = 0; n < SIZE; n++)
    result[ n ] = matrix[ n ][ n ];
}


In both cases, notice that the array is a standard array argument to the function. I presume your issue is that FPGA does not have 'vector's (I have not programmed an FPGA), but if it were to work over vectors that would be an easy change. You could even return a new vector as the result type of the function. Or whatever.

Notice also that you do not need to perform a whole bunch of checks inside your loop IFF you are sure that you are supplying a valid matrix. In the case of C arrays that is pretty much guaranteed (presuming you don’t tell the compiler to shut up if it complains).

If you are using a vector of vector or something for your matrix, you should still make the effort to remove validation from the function — don’t permit invalid matrices to exist in any context where the function may be called.


Hope this helps.
Last edited on
Thank you Duthomhas(11898). The problem is solved. However, my answers are in Nx1 vector. Can you teach me how to transform the Nx1 vector into 1xN vector?
Your help is really appreciated. Thank you.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <complex>


using namespace std;

const int n = 4;

int main()
{


	complex<double> Z[4][4] = { { 1, 4, 2, 4 },{ 3, 4, 1, 5 },{ 6, 2, 3, 4 }, { 7, 8, 1, 3 } };
	complex<double>vecA[n],  vecD[n], vecB[n], vecAlpha[n];


	for (int i = 0; i < n; i++)
	{ 
		
			vecD[i] = Z[i][i];
		
	}

	for (int i = 0; i < n-1; i++)
	{
		vecA[i] = Z[i][i + 1];

	}

	for (int i = 1; i < n; i++)
	{
		vecB[i] = Z[i][i-1];

	}

	std::cout << "\nVector D:" << "\n";
	for (int i = 0; i<n; i++)
	{
		
			std::cout << vecD[i] << ' ';
			std::cout << std::endl;
	}

	std::cout << "\nVector A:" << "\n";
	for (int i = 0; i < n-1; i++)
	{
		std::cout << vecA[i] << ' ';
		std::cout << "\n";
	}

	std::cout << "\nVector B:" << "\n";
	for (int i = 1; i < n; i++)
	{
		std::cout << vecB[i] << ' ';
		std::cout << "\n";
	}

	system("pause");
	return 0;
}


Last edited on
Draw a picture.
> However, my answers are in Nx1 vector.
> Can you teach me how to transform the Nx1 vector into 1xN vector?
your vector has size N, one dimension
it is not 1xN or Nx1, it is just N
view it as you want.
This is my answer in Nx1 vector:

Vector D:
(1,0)
(4,0)
(3,0)
(3,0)

Vector A:
(4,0)
(1,0)
(4,0)

Vector B:
(3,0)
(2,0)
(1,0)

I would like to have is 1xN vector as below:
Vector D:
(1,0) (4,0) (3,0) (3,0)

Vector A:
(4,0) (1,0) (4,0)

Vector B:
(3,0) (2,0) (1,0)
> I would like to have is 1xN vector as below:

So don't print a new line after each element.
1
2
3
4
5
std::cout << "\nVector D:\n" ;

for (int i = 0; i<n; i++) std::cout << vecD[i] << ' '; // do not print a new line within the loop

std::cout << '\n' ; // print a new line after the loop is completed 

Thank you. It is solved.
Topic archived. No new replies allowed.