How to cycle through matrix blocks? - c

I have some matrix which I want to cycle through blocks, the matrix could be of many different sizes, but I can know the size, is there a way to fast cycle through blocks?
i.e: to fast output the indexes of the blocks, suppose a matrix of 4*4 I should have:
Block1: (0,0),(0,1)(1,0)(1,1)
Block2: (0,2),(0,3)(1,2)(1,3)
Block3: (2,0),(2,1)(3,0)(3,1)
Block4: (2,2),(2,3)(3,2)(3,3)
Where the indexes are (row,col).
For blocks I mean a submatrix of size sqrt(matrixSize)* sqrt(matrixSize) where matrix is a matrix of matrixSize*matrixSize.
For example a matrix of 4*4 has 4 blocks of 2*2, a 9*9 has 9 blocks of 3*3...
I am working in C, but I think that the pseudocode is useful also, I only need the loop on the indexes.

I managed to do it, it's coded in c ...
The variable 'matrix_size' contains the number of rows(or columns) of the matrix.
The variable 'block' contains the precomputed size of one block of the matrix i.e: the sqrt of matrix_size.
for(int i = 0; i< matrix_size; i++)
{
fprintf(stdout, "Block %u: ", i);
for(int k= ((i/block)*block) ; k < (((i/block)*block) + block) ;k++)
{
for(int j = ((i%block)*block) ; j< (((i%block)*block) + block); j++)
{
fprintf(stdout,"(%u,%u)",k,j);
}
}
fprintf(stdout, "\n");
}

Related

Extend the dimensions of a 2D array in eclipse using C programming

I have a 2D array named H_initial (3 rows 3 cols) filled with binary values, zeros and ones. Now I need to extend the size of the 2D array H_initial to another 2D array H_final (i.e 6 rows 6 cols) by replacing zeros in H_initial with a 2*2 zero matrix and ones in H_initial with 2*2 identity matrix.
I first created a 6*6 zero matrix and then tried to replace the '1' in H_initial with 2*2 identity matrix using the below code but i'm not getting the required output. I'm programming in C using Eclipse for windows. Also, I'm new to C programming and I don't have enough knowledge on pointers, dynamic memory allocation. Could someone help me here please.
#define ROWS 6
#define COLS 6
int main()
{
int i,j,a,b,H_final[6][6];
// Create a H_initial matrix of size (3x3)
int H_initial[3][3]={{0, 0, 1}, {0, 1, 0}, {1, 0, 0}};
printf("H_initial= \n");
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
printf("%d\t",H_initial[i][j]);
}
printf("\n");
}
// Create a zero matrix of size (6*6)
printf("H_final=\n");
for(a=0; a<6; a++)
{
for(b=0; b<6; b++)
{
H_final[a][b] = 0;
printf("%d\t",H_final[a][b]);
}
printf("\n");
}
// Create H_final by replacing 1 with 2*2 identity matrix
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(H_initial[i][j]==1)
{
for(m=0;m<2;m++)
{
for(n=0;n<2;n++)
{
if(m==n)
{
H_final[2*i+m][2*j+n]=1;
}
}
}
}
}
}
What you're doing with the inner loops:
for(m=0;m<1;m++)
{
for(n=0;n<1;n++)
{
if(m==n)
{
H_final[2*i+m][2*j+n)]=1;
}
}
}
would almost work, except that your loops only count from 0 to 0 so you only access the top-left element of the 2x2 square. If you use eg. for(m=0; m<2; m++) and for(n=0; n<2; n++) that should fix it. You also have a stray ) to remove in the loop body where you access H_final.
It's overly complicated, though, since you can do the same thing with a one-liner without those inner loops:
H_final[2*i][2*j] = H_final[2*i+1][2*j+1] = 1;

Array overwritten after dynamic memory allocation in C

I'm writing a program that converts an array of integer vectors to an adjacency matrix , an (n+1)x(n+1) array. When in the function i have written to do this the dynamic memory allocation from setting up the int** seems to overwrite the n+1 and n+n elements of the integer vector.
int** makeAdjMatrix(IntVec* Vec, int length) { //allocates a new nxn array
printf(" madm test %d \n" , Vec[1]->data[6]);
//confirming that the intvec entered okay
int** new;
new = (int**)malloc(length+1*length+1*sizeof(int*))
printf(" madm test %d \n" , Vec[1]->data[6]);
// confirming that something happenend to the intvec
for (int i = 0; i <= length + 1; i++) {
new[i] = (int*)malloc(length + 1*sizeof(int));
}
for (int i = 1; i <= length+1; i++) {
for (int j = 1; j <= length+1; j++) {
new[i][j] = 0;
}
}
outputs normally for all elements in the vector data structure except those n+1 and above. n in this case being 5.
the above code prints
test 1
test 33
segfault
(because there is no 33rd indices in the array which the code referrences later)
is this memory exhaustion? how am I overwriting a previously allocated array on the heap? this might be a bit vague, this is my first question go easy on me. by the way this only happens when the vector array has repeated identical input.
how bad did I mess up?

Tile matrix multiplication when M doesn't equal N?

Every algorithm I've come across always uses a square matrix for tiling matrix multiplication. Is it possible to tile MMM when the two matrices are of completely different sizes?
This is the code I'm using at the moment and I would like to try and add tiling to improve my performance.
#pragma omp parallel shared(x, R, r, row) private(i, j, k, temp)
{
#pragma omp for
for (k = 0; k < x->n; k++){
for (i = row; i < row+2; i++){
temp = x->v[i*x->n+k];
for (j = 0; j < R->n; j++){
r[i*R->n+j] += temp*R->v[k*R->n+j];
}
}
}
}
The variable x, R, and r are matrix structures with m, n, and v defined to hold the size and data. Matrix x is a rotation matrix, so it is an identity matrix with data in two rows. That's why I am limiting the multiplication to two rows only.
Matrix x therefore has a size of 2xn and R has a size of mxn. Note: It has been defined that x's n is always R's m so there is no size mismatch.
Is it possible to tile this type of mismatched matrix multiplication and still get a performance gain?

How do i select a number in a matrix in c?

So I have made a matrix, that's formed by (NxN). And the numbers for the matrix are put in through user input into a multidimensional array. I'm using pointers and malloc. So I have to select a number in the array to then get the sum of adjacent numbers, the number is selected just by saying the position. So just saying the 3rd number in the matrix. I am a little confused on how to just select a number, I have a general idea of incrementing to get to the right position? Would this be right? And will this then make it harder or easier to then get the sum of the adjacent numbers?
Just a little confused on how to then do this with a multidimensional array, would i just turn it back into a single array?
This is how i create the matrix:
for(i = 0; i< matrixSize; i++)
{
for(j=0; j < matrixSize; j++)
{
scanf("%d", &matrixValues[i][j]);
}
}
If you mean number in a matrix as follows (example for matrixSize == 4):
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
you can just calculate indexes from number
matrixValues[number/matrixSize][number%matrixSize]
EDIT:
For case when your 2D arreay defined as
int matrixValues[matrixSize][matrixSize];
All elements allocated in memory sequentially, i.e. element matrixValues[1][0] is exact after matrixValues[0][matrixSize-1], so you can use number as shift from adress of element matrixValues[0][0], e.g.:
*(((int*)matrixValues) + number)
For your example it can be
int matrixValues[matrixSize][matrixSize];
// input as 2D array
int i, j;
for(i = 0; i< matrixSize; i++)
{
for(j=0; j < matrixSize; j++)
{
scanf("%d", &matrixValues[i][j]);
}
}
// using address of matrix as begining of array
int* fakeArray = (int*)matrixValues;
// output as 1D arrray
int n;
for(n = 0; n < matrixSize * matrixSize ; n++)
{
printf("%d ", fakeArray[n]);
}

MPI Broadcasting dynamic 2D array to other processors

I have searched many explanations, but I think I could not figure out how I can do this situation. I want to do something like that:
Using master processor, I am creating a dynamic 2D array. Then I want to;
1- send this array to other processors. And each processor prints this 2D array
2- send part of this array to others. And each processor prints their part to the screen.
For example; I have 2D array 11*11 and 4 processors. rank 0 is master. Others are slaves. For the first situation, I want to send all array to rank 1, rank 2, and rank 3. And for the second situation, I want to share rows to slaves. 11/3 = 3. Therefore rank 1 takes 3 rows, rank 2 takes 3 rows, and rank 3 takes 5 rows.
Here is my code:
int processorID;
int numberOfProcessors;
int main(int argc, char* argv[]){
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD ,&numberOfProcessors);
MPI_Comm_rank(MPI_COMM_WORLD ,&processorID);
double **array;
if(MASTER){
array = (double**) malloc(11*sizeof(double *));
for(i=0; i<11; i++){
array[i] = (double *) malloc(11*sizeof(double));
}
for(i=0; i<11; i++){
for(j=0; j<11; j++){
array[i][j] = i*j;
}
}
}
MPI_Bcast(array, 11*11, MPI_DOUBLE, 0, MPI_COMM_WORLD);
if(SLAVE){
for(i=0; i<11; i++){
for(j=0; j<11; j++){
printf("%f ", array[i][j]);
}
}
}
MPI_Finalize();
return 0;
}
according to these link ; MPI_Bcast a dynamic 2d array ; I need to create my array as;
if (MASTER){
array = (double**) malloc(121*sizeof(double))
for(i=0; i<11; i++){
for(j=0; j<11; j++){
array[i][j] = i*j; // this is not working.
}
}
}
but if I do this, I cannot initialize each member in the array. Inner for loops are not working. I could not find any way to solve it.
And for my second question, I followed this link sending blocks of 2D array in C using MPI . I think I need to change the inside of if(SLAVE). I should create 2D subArrays for each slave processor. And I need to use MPI_Scatterv. But I could not understand completely.
int main() {
...
...
MPI_Scatterv() // what must be here?
if(SLAVE){
if(processorID = numberOfProcessor-1){
subArray = (double**) malloc(5*sizeof(double *)); // beacuse number of row for last processor is 5
for(i=0; i<11; i++){
array[i] = (double *) malloc(11*sizeof(double));
}
}
else {
subArray = (double**) malloc(3*sizeof(double *));
for(i=0; i<11; i++){
array[i] = (double *) malloc(11*sizeof(double));
}
}
}
}
C does not really have multidimensional arrays. I would recommend storing your values in a regular 1D buffer, and then calculating correct indices from 1D values. Like so:
double* data = (double*)malloc(sizeof(double)*11*11);
// Now, to access data[i][j], simply do:
data[j + i*11] = ...; // this "maps" 2D indices into 1D
This will spare you all the trouble with the hierarchical malloc-ing, and it can easily be passed to the MPI APIs.
You can't use an array of pointers (what you are incorrectly calling a "2D array"), because each row pointer is not portable to another node's address space.
The code you quoted for creating a 2D array in a linear memory allocation is perfectly correct, all you need to do is index that memory in row major order, so that the loops become:
double* array = (double*) malloc(121*sizeof(double));
if (MASTER){
for(i=0; i<11; i++){
for(j=0; j<11; j++){
array[j+i*11] = i*j; // row major indexing here
}
}
}
/* Scatter code follows */
You can safely scatter this sort of array to multiple nodes.

Resources