Concatenate two matrices in C - c

I'm trying to concatenate the same matrix in C, and the only idea that crossed to my mind is addition, but it doesn't work. For example, if I have: {1,1;2,2}, my new matrix should be {1,1,1,1;2,2,2,2}. I want to double the number of rows. I Googled, but I didn't find anything.
Here is my code:
matrix2=realloc(matrix1,sizeof(int*)*(row));
int i,j;
for(i=0;i<row;i++){
for(j=0;j<col;j++){
matrix2[i][j]=matrix1[i][j]+matrix1[i][j];
}
}

Use the psuedocode I provide below. Note that for any C before C99, you cannot instantiate arrays with int matrix[2*W][H] (if W and H are not #defines)
Given matrix1 and matrix 2 of equal W,H
make matrix3 of 2*W,H
for h to H
for i to W
matrix3[h][i] = matrix1[h][i]
matrix3[h][i+W] = matrix2[h][i]
Making the matrix will require 1 malloc per row, plus 1 malloc to store the array of row pointers.
Note how you will need 2 assignments in the loop instead of the one you had before. This is because you are setting in two places.

You sound like you have a background with higher level languages like matlab. In C the plus operator does not concatenate matrices. This will add the values in the matrices and store the new value into the new matrix.

Here we are copying the input matrix into a new matrix twice
for(int i = 0; i < m; i++){for(int j = 0; j < n;j++)
{ mat2[i][j] = mat[i][j];}}
for(int i = 0 ; i < m ; i++){for(int j = n; j < (2*n) ; j++){ mat2[i][j] = mat[i][j-n];}}

Related

Obtaining a submatrix from a squared matrix in C

I want to find a way to obtain a submatrix from an initial bigger squared matrix in c , more specifically , the bottom right submatrix . Then i want the for cycle to give me all the submatrix that i can obtain from the original squared matrix.
I found some code online :
int initial_matrix[3][3]
int submatrix[2][2];
for( int i = 0; i < R - r + 1; i++){
for(int j = 0; j < C - c + 1; j++){
submatrix[i][j]=initial_matrix[i][j]
}
}
where :
R is the number of rows of the initial matrix (so in this case R=3)
C is the number of columns of the initial matrix (so in this case C=3)
r is the number of rows of the submatrix that i want to obtain (so in this case r=2)
c is the number of columns of the submatrix that i want to obtain (so in this case c=2)
But this cycle only gives me the upper left submatrix , while I want the bottom right and then expand it so that it gives me all the possible submatrix of the initial matrix.
At first your indices in the loops are not correct! You want to fill in your target matrix rows from indices 0 to r and columns from indices 0 to c so your loops need to look like:
for(size_t i = 0; i < r; ++i)
{
for(size_t j = 0; j < c; ++j)
{
// ...
}
}
From here on you now can simply assign your target matrix at indices i and j:
submatrix[i][j] = ...;
Problem is that these are not the same indices as in your source matrix (unless you want to use the top-left corner submatrix), so you need to translate the indices to the appropriate positions within the source matrix. Luckily, this is not difficult; if the top-left corner of the submatrix within the source matrix is at row r0 and column c0 then you simply need to add these to the corresponding loop indices, thus you get:
... = initial_matrix[r0 + i][c0 + j];
In your case this would mean e.g. [1 + i][1 + j] to get the bottom-right submatrix with both i and j counting up from 0 to excluded 2 (i.e. counting 0 and 1).

How do I implement the Laplace expansion algorithm in c?

I'm having trouble figuring out a way to make this algorithm work, as I can't figure out how to do the middle part of the problem. Here's my code so far:
int det(int matrixSize, int matrix[][matrixSize]){
int determinant = 0, matrixValues[matrixSize * matrixSize], matrixFirstRowValues[matrixSize * matrixSize];
for(int i = matrixSize; i > 2; i--){
for(int row = 0; row < matrixSize; row++){
for(int col = 0; col < matrixSize; col++){
matrixFirstRowValues[row + (matrixSize - i)] = matrix[1][col + (matrixSize - i)];
//copies the first row values for an array until we have a 2x2 matrix
}
}
}
//multiply the values in matrix Values by their respective matrix without
//the row and column of these values times -1^row+col
determinant += (matrix[matrixSize-1][matrixSize-1] * matrix[matrixSize-2][matrixSize-2])
- (matrix[matrixSize-1][matrixSize-2] * matrix[matrixSize-2][matrixSize-1]);
return determinant;
}
Being the matrix, a 2-dimensional array with the size of matrixSize, I iterate through it until I'm left with a 2x2 matrix, copying each value of the first row to a new array.
Those values have to be multiplied by the matrix that it's left when I remove the row and column where that value is.
This is the principle of the laplace expansion. The part that's giving me trouble is getting those matrices that are left by removing rows and columns, as I want this to work for a nxn matrix.
Then, in the end the sum that to the det of a 2x2 matrix.
How can I do the middle part (where the comments are) with my current setup?
Those values have to be multiplied by the matrix that it's left when I
remove the row and column where that value is.
You have to multiply with the cofactor matrix whose entries are the determinants of the matrices that are left over when removing the i-th row and j-th column.
Naturally, this is the setup for a recursive algorithm, since the determinant of the bigger matrix is expressed in terms of the determinants of smaller matrices: if A = (a_{ij}) is the matrix, then det(A) = sum j = 1..n: a_{ij} * det(M_{ij}), where M_{ij} is the minor matrix that arises from A when removing the i-th row and j-th column where i is fixed. The base case being the 2-by-2 matrices, maybe also 3-by-3 matrices.
The problem that arises is that an n-by-n matrix produces n matrices M_{ij} of size (n-1)-by-(n-1), each of which produces n-1 matrices of size one less and so on until the base case is reached, at which point you'll have to keep track of n!/2 matrices. (It becomes apparent at this point that Laplace expansion is a rather costly algorithm, any algorithm based on Gauss elimination will be far more efficient. But that is just an aside, since we are discussing Laplace expansion.) If done in an iterative fashion, this has to be done manually, a recursive algorithm will have implicit means of bookkeeping via stack frames.
Your approach
Let's have a look at the piece of code that you have provided. It eludes me what precisely you are trying to achieve. Take for instance the statement in the innermost loop which iterates over col:
matrixFirstRowValues[row + (matrixSize - i)] = matrix[1][col + (matrixSize - i)];
For as long as col changes in the innermost loop, both row and i are fixed, so you are assigning and reassigning from (apparently) the second row in matrix to the same entry in matrixFirstRowValues. Not only that, you assign from an index range (matrixSize-i) .. (2*matrixSize - (i+1)) which exceeds the range of the column unless i == matrixSize, which is only the case for the first value of i.
As I mentioned before, in the end you do not end up with just one 2-by-2 matrix but n!/2.
Copying except i-th row and j-th column
Looking at the matrix with i-th row and j-th column removed, you end up with four submatrices (some of which may be empty). Restricting yourself to expansion along the first row, then you are dealing with just two submatrices (still some of which may be empty). You may use two loops, one for the matrix to the left of the j-th column and to the right - or, as suggested in a previous answer - choose to skip the j-th column using continue to cycle the loop without updating the target column index. If col marks the current colum to remove (the current row is always 0), iterate r over all rows, and c over all columns and break the column loop in two pieces at c == col. Let's say, the target matrix is called minor, then it would look like this:
// expand along first row
for(col = 0; col < matrix_size; col++) {
// copy into minor matrix, left side then right side
for(r = 1; r < matrix_size; r++) {
for(c = 0; c < col; c++) {
minor[r-1][c] = matrix[r][c];
}
for(c = col+1; c < matrix_size; c++) {
minor[r-1][c-1] = matrix[r][c];
}
}
// use "minor" matrix at this point to calculte
// its determinant
}
The index shift r-1 is due to the removal of the first row.
A complete recursive Laplace expansion
As I mentioned before, the Laplace expansion of the determinant lends itself naturally to a recursive algorithm. I will do some changes to your setup, i will not use variable length arrays which are stack allocated, I will instead use heap allocated memory. Since the expansion, if the space is not reused, has an exponential space requirement, the stack might quickly get exhausted already for matrices of moderate size. Consequently, I will need an additional parameter to report back memory allocation failures via an intent out parameter which I call is_valid.
You will recognise the above matrix copy procedure with a little different names and an additional pointer dereference, since I operate with n-by-n matrices on the heap. I hope it will not lead to too much confusion.
#include <stdio.h>
#include <stdlib.h>
#define SQR(x) ((x)*(x))
int laplace_det(int matrix_size, const int (*mat)[][matrix_size], int *is_valid) {
// base cases
if(matrix_size == 1)
return (*mat)[0][0];
if(matrix_size == 2)
return (*mat)[0][0] * (*mat)[1][1] - (*mat)[1][0] * (*mat)[0][1];
// recusive case, matrix_size > 2
// expansion indiscriminately along the first row
//
// minor matrix with i-th row and j-th column
// removed for the purpose of calculating
// the minor.
// r, c row and column index variables
// col current column in expansion
// d determinant accumulator
//
int r, c, col, d = 0;
int (*minor)[matrix_size-1][matrix_size-1] = calloc(SQR(matrix_size-1), sizeof(int));
if(!minor) {
*is_valid = 0;
return 0;
}
// expand along first row
for(col = 0; col < matrix_size; col++) {
// copy into minor matrix, left side then right side
for(r = 1; r < matrix_size; r++) {
for(c = 0; c < col; c++) {
(*minor)[r-1][c] = (*mat)[r][c];
}
for(c = col+1; c < matrix_size; c++) {
(*minor)[r-1][c-1] = (*mat)[r][c];
}
}
// calculate minor
int temp_d = laplace_det(matrix_size-1, minor, is_valid);
if(!is_valid) {
free(minor);
return 0;
}
d += (col & 1 ? -1 : 1) * (*mat)[0][col] * temp_d;
}
// free resources
free(minor);
return d;
}
Example driver program:
int main(void) {
int is_valid = 1;
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int det_m = laplace_det(3, &matrix, &is_valid);
if(is_valid) {
printf("determinant %d\n", det_m);
}
}
An iterative approach
If you wanted to do the same thing iteratively, you will need to provide space for all n-1 submatrices of smaller size. As the recursive case shows, you can reuse the same space for all submatrices of the same size, but you cannot use that space for matrices of smaller size because each matrix has to spawn all submatrices of size one smaller, one for each column.
Since the original size of the matrix is not known beforehand, traversing all these matrices in a general way is difficult to realise and will require a lot of bookkeeping that we get for free keeping these values in their respective stack frames in the recursive case. But I suppose keeping the current column selector in an array of size matrixSize, as well as an array of pointers to the submatrices, it will be possible to rewrite this iteratively.
I tried to solve the laplace expansion using recursion method. May this help you
Code:
#include <stdio.h>
int determinant(int size,int det[][4]) // size & row of the square matrix
{
int temp[4][4],a=0,b=0,i,j,k;
int sum=0,sign; /* sum will hold value of determinant of the current matrix */
if(size==2)
return (det[0][0]*det[1][1]-det[1][0]*det[0][1]);
sign=1;
for(i=0;i<size;i++) // note that 'i' will indicate column no.
{
a=0;
b=0;
// copy into submatrix and recurse
for(j=1;j<size;j++) // should start from the next row !!
{
for(k=0;k<size;k++)
{
if(k==i) continue;
temp[a][b++]=det[j][k];
}
a++;
b=0;
}
sum+=sign*det[0][i]*determinant(size-1,temp); // increnting row & decrementing size
sign*=-1;
}
return sum;
}
//Main function
int main()
{
int i,j;
int det[4][4] = {{1, 0, 2, -1},
{3, 0, 0, 5},
{2, 1, 4, -3},
{1, 0, 5, 0}
};
printf("%d",determinant(4,det));
}
Cheers!

How to pass a row from a matrix to a new array in C

So in c I have a data matrix that is n x m. How can I extract a single row to pass it to a new variable. My python code looks like this:
new_var = data[i, :]
Please help me translate into C.
My way is
int i = rand(num_rows);
double new_var[num_cols];
for (j = 0; j < num_cols; j++)
{
new_var[j] = data[i][j];
}
Please comment.
Many thanks
What you are doing is correct. But I don't get what you are trying to do with this -
int i = rand(num_rows); // using rand like this is incorrect syntax.
If you want a random number between 0 to num_rows. Correct will be -
int i = rand()%num_rows;
See here how to use rand.

"C" i couldnt understand how i can add two matrises

I'm a begginer about c and i need help about it please help
{
int matris[2][2];
for(int i=0;i<2;i++)
{
for(int j=0;j<4;j++)
{
printf("Sayi giriniz: "); scanf("%d",&matris[i][j]);
}
}
for(int i=0;i<3;i++)
{
for(int j=0;j<2;j++)
{
printf("%d ",matris[i][j]);
}
printf("\n");
}
}
As a beginner, you need to realize that programming is nothing more than problem-solving, well there is the bit about expressing the answer in a programming language.
Doing matrix addition -- how do you do it, how would a mathematician define it? Arnaldo has given you the answer to this, $A + B = C$ where $c_{ij} = a_{ij} + b_{ij}$. So already, this starts to set some restrictions on the two matrices that your are working with, notably they have to have the same number of rows and columns.
Representation of matrices -- ok, now that you know how to add to matrices, you need to figure out how you are going to represent a matrix in your program. Computer memory is a one-dimensional array of storage units, so we need to map our two dimensional structure onto this one-dimensional array. There are two ways of doing this. The first is row major which means that we write the first row to memory, then the second row and so on. The second is column major which means that we write the first column to memory and then the second row.
Consider the following 2x3 matrix:
| a b c |
| d e f |
in row-major form, it would be laid out in memory as:
+---+---+---+---+---+---+
| a | b | c | d | e | f |
+---+---+---+---+---+---+
and in column-major form, in would be laid out in memory as:
+---+---+---+---+---+---+
| a | d | b | e | c | f |
+---+---+---+---+---+---+
Remember that computer science is zero based, so where a mathematician would designate the first element in the first row as a_{11}, we will be using zero based indicies so we will designate it as a_{00}.
Most modern program languages use row-major form to store two dimensional arrays (or in this discussion matrices). So what you might ask? Well, because we are mapping a two dimensional array to a one dimensional array, and all we really know about the one dimensional array is its starting point in memory, we need to be able to change the pair (row, col) into a single index. You should convince yourself that the following equation is correct, assuming that nRow and nCol are the number of rows and columns in the matrix.
index = nCol * row + col
So, now write some code to add to matrices together. In pseudo-code form this would be:
A <-- read in first n-by-m matrix
B <-- read in second n-by-m matrix
C <-- initialize a n-by-m matrix to all zero elements.
for(r = 0; r < nRow; r++)
for(c = 0; c < nCol; c++)
C[r][c] = A[r][c] + B[r][c]
print C
It is an implementation detail to decide if you want to use fix sized matrices, i.e. 'A[2][2]', or potentially use a dynamically allocated matrix, i.e. 'A = malloc(nRow * nCol * sizeof(int));' (assuming we are storing integers). This will determine exactly how the addition line in the above pseudo-code would be written.
Hope this helps, and kinda show you how to approach problems like this.
Don't be afraid to ask additional questions if you get stuck on attempting the implementation.
Best of Luck,
T
I don't fully understand what your question is, but I can definately show you how to add two matricies of the same length elementwise, if that's what you're looking for.
#include <stdio>;
int main()
{
//this part is declaring the two arrays you want to add,
//and the array you want to store the result in.
int arrayA[3];
int arrayB[3];
int result[3];
//this part is just initializing the data in the array
arrayA[0] = 1;
arrayA[1] = 2;
arrayA[2] = 3;
arrayB[0] = 5;
arrayB[1] = 6;
arrayB[2] = 7;
//loops from 0 to 2, and adds the nth element of arrayA and
// arrayB to store in result
for(int n =0; n < 3; n++)
{
result[n] = arrayA[n] + arrayB[n];
}
//at this point, result is the addition of your arrays.
//You can print it, or whatever it is you wanted to do with it.
return 0;
}
There are many different things that could be 'adding matricies', but this is one of them.
However, the code you submitted looks like you're trying to store numbers from the keyboard into a 2D array. You're on the right track there, but on your first nested for loop your inner loop goes too far, so it's going outside of the array bounds. Try more liek this:
int matris[2][2];
for(int i=0;i<2;i++)
{
//you had j<4 here. That will put you in invalid memory!
for(int j=0;j<2;j++)
{
printf("Sayi giriniz: "); scanf("%d",&matris[i][j]);
}
}
//you had i<3 here. That will also put you in invalid memory.
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
printf("%d ",matris[i][j]);
}
printf("\n");
}
I hope I've addressed whatever question you were going for.
İyi şanslar!

i want to combine two 2d array into array with points

I want to combine two 2D arrays into one Nx2 array.
For example a=[1,2,3] b=[4,5,6], and I want to make c=[(1,4),(2,5),(3,6)].
i want to do it in python, but i don't know what command should i use. any hint?
you can do that in any language you want, the algorithm will likely be the same. What you want to do is
create matrix c
read through each array
grab the point at index i in each
put a[i] into matrix row i column 0
put b[i] into matrix row i column 1
here's some pseudo code to illustrate
int [][] c;
for (int i = 0; i < a.length; i++) {
c[i][0] = a[i];
c[i][1] = b[i];
}

Resources