Efficient method to store a Lower Triangular Matrix using row-major mapping
Given a lower triangular matrix Mat[][], the task is to store the matrix using row-major mapping.
Lower Triangular Matrix: A Lower Triangular Matrix is a square matrix in which the lower triangular part of a matrix consists of non-zero elements and the upper triangular part consists of 0s. The Lower Triangular Matrix for a 2D matrix Mat[][] is mathematically defined as:
- If i < j, set Mat[i][j] = 0.
- If i >= j, set Mat[i][j] > 0.
Illustration: Below is a 5×5 lower triangular matrix. In general, such matrices can be stored in a 2D array, but when it comes to matrices of large size, it is not a good choice because of its high memory consumption due to the storage of unwanted 0s.
Such a matrix can be implemented in an optimized manner.
The efficient way to store the lower triangular matrix of size N:
- Count of non-zero elements = 1 + 2 + 3 + … + N = N * (N + 1) /2.
- Count of 0s = N2 – (N * (N + 1) /2 = (N * (N – 1)/2.
Now let us see how to represent lower triangular matrices in our program. Notice that storing 0s must be avoided to reduce memory consumption. As calculated, for storing non-zero elements, N*(N + 1)/2 space is needed. Taking the above example, N = 5. Array of size 5 * (5 + 1)/2 = 15 is required to store the non-zero elements.
Now, elements of the 2D matrix can be stored in a 1D array, row by row, as shown below:
Apart from storing the elements in an array, a procedure for extracting the element corresponding to the row and column number is also required.
Using Row-Major Mapping for storing lower triangular matrix, the element at index Mat[i][j] can be represented as:
Index of Mat[i][j] matrix in the array A[] = [i*(i – 1)/2 + j – 1]
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
static int N = 5;
class Matrix {
public :
int * A;
int size;
};
void Set(Matrix mat, int i, int j, int x)
{
if (i >= j)
mat.A[i * (i - 1) / 2 + j - 1] = x;
}
int Get(Matrix mat, int i, int j)
{
if (i >= j)
return mat.A[i * (i - 1) / 2 + j - 1];
return 0;
}
void Display(Matrix mat)
{
int i, j;
for (i = 1; i <= mat.size; i++) {
for (j = 1; j <= mat.size; j++) {
if (i >= j)
cout << mat.A[i * (i - 1) / 2 + j - 1]
<< " " ;
else
cout << 0 << " " ;
}
cout << endl;
}
}
Matrix createMat(vector<vector< int > >& Mat)
{
Matrix mat;
mat.size = N;
mat.A = new int [(mat.size * (mat.size + 1)) / 2];
int i, j;
for (i = 1; i <= mat.size; i++)
for (j = 1; j <= mat.size; j++)
Set(mat, i, j, Mat[i - 1][j - 1]);
return mat;
}
int main()
{
vector<vector< int > > Mat = { { 1, 0, 0, 0, 0 },
{ 1, 2, 0, 0, 0 },
{ 1, 2, 3, 0, 0 },
{ 1, 2, 3, 4, 0 },
{ 1, 2, 3, 4, 5 } };
Matrix mat = createMat(Mat);
Display(mat);
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
const int N = 5;
struct Matrix {
int * A;
int size;
};
void Set( struct Matrix* mat,
int i, int j, int x)
{
if (i >= j)
mat->A[i * (i - 1) / 2 + j - 1] = x;
}
int Get( struct Matrix mat, int i, int j)
{
if (i >= j) {
return mat.A[i * (i - 1) / 2 + j - 1];
}
else {
return 0;
}
}
void Display( struct Matrix mat)
{
int i, j;
for (i = 1; i <= mat.size; i++) {
for (j = 1; j <= mat.size; j++) {
if (i >= j) {
printf ( "%d " ,
mat.A[i * (i - 1) / 2 + j - 1]);
}
else {
printf ( "0 " );
}
}
printf ( "\n" );
}
}
struct Matrix createMat( int Mat[N][N])
{
struct Matrix mat;
mat.size = N;
mat.A = ( int *) malloc (
mat.size * (mat.size + 1) / 2
* sizeof ( int ));
int i, j;
for (i = 1; i <= mat.size; i++) {
for (j = 1; j <= mat.size; j++) {
Set(&mat, i, j, Mat[i - 1][j - 1]);
}
}
return mat;
}
int main()
{
int Mat[5][5] = { { 1, 0, 0, 0, 0 },
{ 1, 2, 0, 0, 0 },
{ 1, 2, 3, 0, 0 },
{ 1, 2, 3, 4, 0 },
{ 1, 2, 3, 4, 5 } };
struct Matrix mat = createMat(Mat);
Display(mat);
return 0;
}
|
Java
class GFG
{
static int N = 5 ;
static class Matrix {
int [] A;
int size;
};
static void Set(Matrix mat,
int i, int j, int x)
{
if (i >= j)
mat.A[i * (i - 1 ) / 2 + j - 1 ] = x;
}
static int Get(Matrix mat, int i, int j)
{
if (i >= j) {
return mat.A[i * (i - 1 ) / 2 + j - 1 ];
}
else {
return 0 ;
}
}
static void Display(Matrix mat)
{
int i, j;
for (i = 1 ; i <= mat.size; i++) {
for (j = 1 ; j <= mat.size; j++) {
if (i >= j) {
System.out.printf( "%d " ,
mat.A[i * (i - 1 ) / 2 + j - 1 ]);
}
else {
System.out.printf( "0 " );
}
}
System.out.printf( "\n" );
}
}
static Matrix createMat( int Mat[][])
{
Matrix mat = new Matrix();
mat.size = N;
mat.A = new int [(mat.size*(mat.size + 1 )) / 2 ];
int i, j;
for (i = 1 ; i <= mat.size; i++)
{
for (j = 1 ; j <= mat.size; j++)
{
Set(mat, i, j, Mat[i - 1 ][j - 1 ]);
}
}
return mat;
}
public static void main(String[] args)
{
int Mat[][] = { { 1 , 0 , 0 , 0 , 0 },
{ 1 , 2 , 0 , 0 , 0 },
{ 1 , 2 , 3 , 0 , 0 },
{ 1 , 2 , 3 , 4 , 0 },
{ 1 , 2 , 3 , 4 , 5 } };
Matrix mat = createMat(Mat);
Display(mat);
}
}
|
Python3
N = 5
class Matrix:
def __init__( self , size):
self .size = size
self .A = [ None ] * ( self .size)
def Set (mat, i, j, x):
if i > = j:
mat.A[i * (i - 1 ) / / 2 + j - 1 ] = x
def get(mat, i, j):
if i > = j:
return mat.A[i * (i - 1 ) / / 2 + j - 1 ]
return 0
def display(mat):
for i in range ( 1 , mat.size + 1 ):
for j in range ( 1 , mat.size + 1 ):
if i > = j:
print (mat.A[i * (i - 1 ) / / 2 + j - 1 ], end = " " )
else :
print ( 0 , end = " " )
print ()
def create_matrix(Mat):
mat = Matrix(N)
mat.A = [ None ] * ((mat.size * (mat.size + 1 )) / / 2 )
for i in range ( 1 , mat.size + 1 ):
for j in range ( 1 , mat.size + 1 ):
Set (mat, i, j, Mat[i - 1 ][j - 1 ])
return mat
if __name__ = = '__main__' :
Mat = [[ 1 , 0 , 0 , 0 , 0 ],
[ 1 , 2 , 0 , 0 , 0 ],
[ 1 , 2 , 3 , 0 , 0 ],
[ 1 , 2 , 3 , 4 , 0 ],
[ 1 , 2 , 3 , 4 , 5 ]]
mat = create_matrix(Mat)
display(mat)
|
C#
using System;
public class GFG
{
static int N = 5;
class Matrix {
public int [] A;
public int size;
};
static void Set(Matrix mat,
int i, int j, int x)
{
if (i >= j)
mat.A[i * (i - 1) / 2 + j - 1] = x;
}
static int Get(Matrix mat, int i, int j)
{
if (i >= j) {
return mat.A[i * (i - 1) / 2 + j - 1];
}
else {
return 0;
}
}
static void Display(Matrix mat)
{
int i, j;
for (i = 1; i <= mat.size; i++) {
for (j = 1; j <= mat.size; j++) {
if (i >= j) {
Console.Write( "{0} " ,
mat.A[i * (i - 1) / 2 + j - 1]);
}
else {
Console.Write( "0 " );
}
}
Console.Write( "\n" );
}
}
static Matrix createMat( int [,]Mat)
{
Matrix mat = new Matrix();
mat.size = N;
mat.A = new int [(mat.size*(mat.size + 1)) / 2];
int i, j;
for (i = 1; i <= mat.size; i++)
{
for (j = 1; j <= mat.size; j++)
{
Set(mat, i, j, Mat[i - 1,j - 1]);
}
}
return mat;
}
public static void Main(String[] args)
{
int [,]Mat = { { 1, 0, 0, 0, 0 },
{ 1, 2, 0, 0, 0 },
{ 1, 2, 3, 0, 0 },
{ 1, 2, 3, 4, 0 },
{ 1, 2, 3, 4, 5 } };
Matrix mat = createMat(Mat);
Display(mat);
}
}
|
Javascript
let N = 5;
class Matrix{
A = new Array();
size;
constructor(){ }
}
function Set(mat, i, j, x){
if (i >= j){
mat.A[i * (i - 1) / 2 + j - 1] = x;
}
}
function Get(mat, i, j){
if (i >= j) {
return mat.A[i * (i - 1) / 2 + j - 1];
}
else {
return 0;
}
}
function Display(mat){
let i, j;
for (i = 1; i <= mat.size; i++) {
for (j = 1; j <= mat.size; j++) {
if (i >= j) {
console.log(mat.A[i * (i - 1) / 2 + j - 1] + " " );
}
else {
console.log( "0 " );
}
}
console.log( "<br>" );
}
}
function createMat(Mat){
var mat = new Matrix();
mat.size = N;
mat.A = new Array((mat.size*(mat.size + 1))/2);
let i, j;
for (i = 1; i <= mat.size; i++)
{
for (j = 1; j <= mat.size; j++)
{
Set(mat, i, j, Mat[i - 1][j - 1]);
}
}
return mat;
}
let Mat = [ [1, 0, 0, 0, 0],
[1, 2, 0, 0, 0],
[1, 2, 3, 0, 0],
[1, 2, 3, 4, 0],
[1, 2, 3, 4, 5] ];
var mat = createMat(Mat);
Display(mat);
|
Output:
1 0 0 0 0
1 2 0 0 0
1 2 3 0 0
1 2 3 4 0
1 2 3 4 5
Time Complexity: O(N2)
Auxiliary Space: O(N2)
Last Updated :
23 Nov, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...