Transform an upper triangular matrix into a full matrix C++ - c++

How would look the code that can transform an upper triangular matrix into a full matrix.
The matrix is in a vector, not in a bidimensional array...
so the array
[ 1 2 3 4
0 5 6 7
0 0 8 9
0 0 0 10 ]
would become an array like:
[ 1 2 3 4
2 5 6 7
3 6 8 9
4 7 9 10 ]
could you provide some ideas, I was thinking in applying a kind of module or something...
There is one restriction, I am not using bidimensional arrays
I am usng a vector, so is a unidimensional array

First, you must understand the fundemtnal nature of a reflected matrix. For any i, j, the following assertion is true:
m[i][j] ≡ m[j][i]
So, you need some algorithm to make that true. May I suggest:
for(int i = 0; i < HEIGHT; ++i)
for(int j = 0; j < i; ++j)
m[i][j] = m[j][i];
Note the condition of the 2nd loop. By ensuring that j is always less than i, we restrict our activity to the bottom-left triangle.
Next, you must understand how you have implemented a two-dimensional matrix in a one-dimensional array. It appears that you have established the identity:
m[i][j] ≡ v[i*WIDTH+j]
Substituting, we have:
for(int i = 0; i < HEIGHT; ++i)
for(int j = 0; j < i; ++j)
v[i*WIDTH+j] = v[j*WIDTH+i];

Related

N X 3 matrix shorting and unique element matrix extraction

I am facing problem with a 2D matrix consist of 3 column and N rows. Now I wanted to sort the matrix in such a way that the smallest of the first row is the first element, and so on. The first element of the second row is the smallest number with the smallest value of the first row. and similar to 3rd row. For example,
A B C
5 2 6
6 5 8
2 9 4
4 5 8
2 3 5
2 9 2
so the sorted matrix will be
A B C
2 3 5
2 9 2
2 9 4
4 5 8
5 2 6
6 5 8
Also, it will store the index of them such that
A_i B_i C_i
5 5 5
6 6 6
3 3 3
and so on...
I implemented this using C++ which is not computationally efficient and takes so much time for a very big matrix. How I can Implement this a computationally efficient way and fast?
My current C++ code for the same is as follow
for(int tii=0; tii<f_sizee; tii++){
track_index(tii)=tii+1;
}
for(int chkhk=0;chkhk<f_sizee;chkhk++){
if(check_index(chkhk)==1){
for(int chkhk1=chkhk+1;chkhk1<f_sizee;chkhk1++){
if((Va_mat(chkhk,0)==Va_mat(chkhk1,0))&&(Va_mat(chkhk,1)==Va_mat(chkhk1,1))&&(Va_mat(chkhk,2)==Va_mat(chkhk1,2))){
check_index(chkhk1)=0;
track_index(chkhk1)=seed_ind;
}
else track_index(chkhk)=seed_ind;
}
seed_ind=seed_ind+1;
}
}
int new_dim=sum(check_index);
int new_count=0;
mat unsort_vmat=zeros(new_dim,Va_mat.n_cols);
for(int iij=0; iij<f_sizee; iij++){
if(check_index(iij)==1){
unsort_vmat.row(new_count)=Va_mat.row(iij);
new_count++;
}
}
mat sort_vmat=zeros(new_dim,Va_mat.n_cols);
uvec indices = stable_sort_index(unsort_vmat.col(0));
int contrrS=0;
for(int sort_f=0; sort_f < new_dim; sort_f++){
for(uword sort_f2=0; sort_f2 < Va_mat.n_cols; sort_f2++){
contrrS=indices(sort_f);
sort_vmat(sort_f,sort_f2)=unsort_vmat(contrrS,sort_f2);
}
}
mat sort_vmat2 = zeros(new_dim,Va_mat.n_cols);
sort_vmat2 = sort_vmat ;
double element_tmp=0;
for(int iitr=0; iitr < new_dim; iitr++){
for(int iitk=iitr; iitk < new_dim; iitk++){
if(sort_vmat(iitk,0)==sort_vmat(iitr,0)){
if(sort_vmat(iitk,1)>sort_vmat(iitr,1)){///if error, delete this brace
element_tmp=sort_vmat(iitr,1);
sort_vmat(iitr,1)=sort_vmat(iitk,1);
sort_vmat(iitk,1)=element_tmp;
}
}
}
}
vec new_ind=zeros(f_sizee);
int start_ind=0;
for(int new_index=0; new_index<f_sizee; new_index++){
new_ind(new_index)=start_ind;
start_ind++;
}
int itr_count=0;
for(uword itr1=0; itr1<Va_mat.n_rows; itr1++){
for(int itr2=0; itr2<new_dim; itr2++){
if((Va_mat(itr1,0)==sort_vmat2(itr2,0))&&(Va_mat(itr1,1)==sort_vmat2(itr2,1))&&(Va_mat(itr1,2)==sort_vmat2(itr2,2))){
new_ind(itr_count)=itr2+1;
itr_count++;
}
}
}
int funda=0;
for(unsigned int Faa=0; Faa<Fa_mat.n_rows; Faa++){
for(unsigned int Fab=0; Fab<Fa_mat.n_cols; Fab++){
Fa_mat(Faa, Fab)=new_ind(funda);
funda++;
}
}

How to rotate outer ring of a matrix by n step in C++?

I want to rotate just the outer ring of a matrix clockwise.
Where n=number of steps to be rotate clockwise.
Suppose if I have a 4x5 matrix.
1 2 3 4 5
6 7 8 9 0
5 4 2 5 7
8 2 7 9 3
Now if n=1 the output should be :-
6 1 2 3 4
5 7 8 9 5
8 4 2 5 0
2 7 9 3 7
I have tried the logic of :
int temp = im[i][j];
im[i][j] = im[n-1-j][i];
im[n-1-j][i] = im[n-1-i][n-1-j];
im[n-1-i][n-1-j] = im[j][n-1-i];
im[j][n-1-i] = temp;
But I know this logic is completely wrong as it is moving the whole matrix.
You can do it like this:
Map and copy the border to a flat array
Apply std::rotate
Copy rotated array back into the border
Here is a sample implementation:
void rotate_border(int m[R][C], int n) {
vector<int> tmp(2*(R+C-2), -1);
for (size_t c = 0 ; c != C ; c++) {
tmp[c] = m[0][c];
tmp[c+C+R-2] = m[R-1][C-c-1];
}
for (size_t r = 1 ; r != R-1 ; r++) {
tmp[C+r-1] = m[r][C-1];
tmp[2*C+R-3+r] = m[R-r-1][0];
}
std::rotate(tmp.begin(), std::next(tmp.begin(), n), tmp.end());
for (size_t c = 0 ; c != C ; c++) {
m[0][c] = tmp[c];
m[R-1][C-c-1] = tmp[c+C+R-2];
}
for (size_t r = 1 ; r != R-1 ; r++) {
m[r][C-1] = tmp[C+r-1];
m[R-r-1][0] = tmp[2*C+R-3+r];
}
}
Demo.
Positive numbers rotate border counterclockwise. For clockwise rotation subtract the number from the size of the border. For example, 4✕5 matrix has the border of size 14, i.e. 5+(4-2)+5+(4-2). Hence, rotating by 1 clockwise requires rotating by 14-1.

Big O Notation Confusion (C++)

int f(const std::vector<int>& v) {
int result = 0;
for (int i = 0; i < v.size(); ++i) { O(N)
for (int j = v.size(); j >= 0; j -= 2) { O(N/2)
result += v.at(i) * j;
}
}
return result;
}
The inner for loop is O(N/2), however I am wondering why this is because
For example, if v.size() is 10, then
10 >= 0 ✓
8 >= 0 ✓
6 >= 0 ✓
4 >= 0 ✓
2>= 0 ✓
0 >= 0 ✓
-2 Fails
The inner for loop could be executed 6 times with an input size of 10
What am I missing?
EDIT* I understand that only highest magnitude is taken into consideration. This question was more about coming up with the original O(N/2 + 1)
Complexity gives you a way to assess the magnitude of time it would take an input of certain size to complete, not the accurate time it would perform with.
Therefore, when dealing with complexity, you should only consider the highest magnitude, without constant multipliers:
O(N/2 + 1) = O(N/2) = O(N)
In a comment, you said:
I understand this, but I am just curious as to how O(N/2) is obtained
Take a look at the following table:
Size of vector Number of time the inner loop is executed:
0 1
1 1
2 2
3 2
...
100 51
101 51
...
2x x + 1
2x + 1 x + 1
If you take the constant 1 out of that equation, the inner loop is O(N/2).

C++ - Can not access reverse indexing

Please forgive me if the title is wrong, or, does not explain the problem correctly.
I'm trying to calculate the LU Decomposition of a matrix. Give the matrix M:
M = [1 2 3],
[1 2 3],
[3 3 0]
Now I'm following some code that was written here: Link
It uses j i in order to calculate the lower decomposition. When I try this approach, I keep getting a "Runtime error time: 0 memory: 3276 signal:11"
The thing that I do not understand is the fact that, when I output i, j inside of the 3x3 loop, I got:
i, j =
0 0 1 0 2 0
0 1 1 1 2 1
0 2 1 2 2 2
Then when output the indexes of j,i I get:
j, i =
0 0 0 1 0 2
1 0 1 1 1 2
2 0 2 1 2 2
Which seems right in terms of the order [0][0][0][2].........[2][2] so why can I not access this, inside my vector?
The code that I have written so far is:
void lu_decomposition(const std::vector<std::vector<double> > &vals)
{
std::vector<std::vector<double> > lower(3);
for(unsigned i=0; (i < 3); i++)
{
lower[i].resize(3);
for(unsigned j=0; (j < 3); j++)
{
if (j < i)
{
lower[j][i] = 0; // This is ok
}else{
lower[j][i] = vals[j][i]; // This is the runtime error
}
}
std::cout << std::endl;
}
}
The code is also visible on ideone
Let's concentrate on these lines:
lower[i].resize(3);
//...
lower[j][i] = vals[j][i];
Is the problem clear now? You're resizing lower[i], but then you're accessing lower[j] even for j > i, which has not been resized yet. If you need to access the matrix in this fashion, you'll have to preallocate it beforehand. That means to drop the resize call and instead initialise the variable like this:
std::vector<std::vector<double> > lower(3, std::vector<double>(3));

Rotate NxN Matrix Counter(anti)-Clockwise 90 Degress

I have a 2D Matrix M[N][N] that I need to rotate counter-clockwise by 90 degrees. I have seen many answers for clockwise rotation but I cannot find counter-clockwise. How similar are the two operations?
If you reverse the order of each individual row and then taken rows in opposite order from a clockwise rotation, you get a count-clockwise rotation.
A B C G D A A D G C F I
D E F -> Clockwise -> H E B -> Reverse -> B E H -> Opposite -> B E H
G H I I F C Rows C F I Ordering A D G
Matrix Counter
Clockwise
Usually it's easier (and more computationally efficient) to do a clockwise rotation rotation on the original matrix in reverse order if you already have a clockwise rotating algorithm available.
1 2 3 9 8 7 3 6 9
4 5 6 -> Reverse -> 6 5 4 -> Clockwise -> 2 5 8
7 8 9 Indices 3 2 1 1 4 7
Matrix Counter
Clockwise
You can also just take 3 clockwise rotations to get to a counter clockwise rotation.
Though in reality it's usually fairly easy to edit the clockwise algorithm to your purposes directly. So I'd only use the above options if you don't care about efficiency and don't want to work through the logic of changing the direction of rotation.
From row(max), decrementing, fill in the result rows(incrementing index) with the values of that column, one after the other (incrementing).
So in a 3 x 3, use (using r, c notation like Excel)
(3, 1), (3, 2), (3, 3),
(2, 1), (2, 2), (2, 3),
etc.
You can just take the transpose 3 times, if you are using a particular matrix library
OK. let us say N =2 to be simple:
1 2
3 4
counter-clockwise 90 degree means that it will become:
2 4
1 3
We have the following rules:
1 last column from top to bottom of original matrix becomes
first row of rotated matrix from left to right
2 first column of original matrix becomes last row of rotated matrix
3 same rules apply to other columns of original matrix
You can easily code this out.
Another way to do is to first do a transpose on the matrix then reverse the order of all rows.
public static void main(String[] args) {
int[][] matrix = createAMatrix(3,3);
List<Stack<Integer>> tiltedMatrix = tiltMatrixBy90Now(matrix, 3);
int[][] newMatrix = new int[3][3];
for(int i = 0; i < 3; i ++) {
for(int j = 0; j < 3; j ++) {
newMatrix[i][j] = tiltedMatrix.get(j).pop();
}
}
//print new matrix
for(int i = 0; i < 3; i ++) {
for(int j = 0; j < 3; j ++) {
System.out.print(newMatrix[i][j]+" ");
}
System.out.println();
}
}
private static List<Stack<Integer>> tiltMatrixBy90Now(int[][] matrix , long order) {
List<Stack<Integer>> stackList = new ArrayList<>();
//filling the stack
for(int i = 0; i< order ; i++) {
stackList.add(new Stack<Integer>());
}
for(int i = 0; i < order; i ++) {
for(int j = 0; j < order; j ++) {
stackList.get(i).push(matrix[i][j]);
}
}
return stackList;
}
private static int[][] createAMatrix(final int a, final int b){
int counter = 1;
int[][] matrix = new int[a][b];
Scanner scanner = new Scanner(System.in);
while(counter <= a*b) {
for(int i = 0; i < a; i ++) {
for(int j = 0; j < b; j ++) {
matrix[i][j] = scanner.nextInt();
counter++;
}
}
}
return matrix;
}
/*
Input matrix (3 by 3)
1 2 3
4 5 6
7 8 9
Output matrix (3 by 3):
3 6 9
2 5 8
1 4 7
Code walk through as text explanation
Create a matrix , in above code It is 3*3 matrix
Creating 3 stacks from each row of 3*3 matrix
Pop from each stack one by one in parallel and and re-creating a matrix.
Printing the new tilted matrix by 90 degree(Anticlockwise).
*/