So, I am trying to make a function that transpose some matrix and save it in another matrix.
In the main function I create a matrix called AB (is a 3D matrix) that is size AB[100][100][2] (in this test) and the terms of the type AB[i][j][0] represents the matrix A and AB[i][j][1] represents the matrix B.
The error is occurring in the big test (AB[100][100][2]) when I run the first loop in the function, that look like that:
void transpose(int size, int matrix[][MAX][2], int index, int index_save){
int auxiliar_matrix[MAX][MAX];
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
auxiliar_matrix[i][j] = matrix[j][i][index];
}
save(matrix, index_save, auxiliar_matrix, size) /*this just save the matrix, isnt wrong*/
}
The function just do not work for the big case and the error is in the first 3 lines. Any idea?
Related
I am trying to copy a 2d array in to another variable by reference to avoid unnecessary computation. I essentially have two 2d arrays, current_array and new_array, and I generate new_array from current_array then replace.
I am trying to program conways game of life using openmp, but I am having problems copying the new array to the old one. I have tried using *current_array=*new_array, ¤t_array=&new_array, ... and all other combinations.
I don't know much about C or pointers but the teacher insists we use C.
void NextArray(int const height, int const width, int const CurrentArray[height][width], int NewArray[height][width]){
for(int i = 0; i < height; ++i){
for(int j = 0; j < width; ++j){
NewArray[i][j] = Newpoint(i,j, CurrentArray);
}
}
}
int main(){
int CurrentArray[height][width];
int NewArray[height][width];
InitialArray=fopen("matrix.txt", "r");
for(long long i = 0; i < height; ++i){
for(long long j = 0; j < width; ++j){
fscanf(InitialArray, "%d", &CurrentArray[i][j]);
}
}
NextArray(height, width, CurrentArray, NewArray);
CurrentArray = NewArray;
return 0;
}
I expect CurrentArray to have the same information that results from the NextArray function, if you define NewPoint like this:
void NextArray(int const i, int const j, int const CurrentArray[height][width]){
if (CurrentArray[i][j]){
return 0;
}
return 1;
}
height = 2, width = 2, and "matrix.txt" as a file with the following:
0 0
1 1
then CurrentArray should be
1 1
0 0
To copy an array to an array of identical type (identical dimensions and element type), use:
memcpy(NewArray, CurrentArray, sizeof NewArray);
To make a pointer that refers to another array, use:
int (*NewArray)[width] = CurrentArray;
This works because, when CurrentArray is used in most expressions, it is automatically converted to a pointer to its first element. Since it is an array of arrays, its first element is an array. That array has type int [width], and a pointer to such an array has type int (*)[width]. So declaring NewArray to with int (*NewArray)[width] defines it to have the right type to be assigned (and act like) a pointer to the first element of CurrentArray.
Given your task, you probably want two separate arrays—you want to have both the old data and the new data available. Your title asks for a “referenced copy”, but you probably do not want a reference to the old array, because then you have only one set of data that is accessed through two different identifiers.
I'm learning about graph data structure in C and I have represented a graph with the adjacency matrix. So far I created the adjacency matrix which means(in my understanding at least) that I have specified 'between which vertices there will be edges' altough I have not yet created any actual nodes. Now after I have done that I want to actually populate my graph with nodes which contain a data type of my own(say each node in a structure which contains some elements). I have googled a lot but all I found was examples on how to create the adjacency matrix but the explanations would stop there without showing how you actually insert new elements in the graph.
I have written the code to populate the adjacency matrix. I have provided the code below:
#include<stdio.h>
#define V 5
void init(int arr[][V])
{
int i,j;
for(i = 0; i < V; i++)
for(j = 0; j < V; j++)
arr[i][j] = 0;
}
void addEdge(int arr[][V],int src, int dest)
{
arr[src][dest] = 1;
}
void printAdjMatrix(int arr[][V])
{
int i, j;
for(i = 0; i < V; i++)
{
for(j = 0; j < V; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int adjMatrix[V][V];
init(adjMatrix);
addEdge(adjMatrix,0,1);
addEdge(adjMatrix,0,2);
addEdge(adjMatrix,0,3);
addEdge(adjMatrix,1,3);
addEdge(adjMatrix,1,4);
addEdge(adjMatrix,2,3);
addEdge(adjMatrix,3,4);
printAdjMatrix(adjMatrix);
return 0;
}
Now my question is: to populate my graph with new nodes do I have to create another array of size noofnodes x noofnodes and populate it? Is that the correct way to do it or is there any other way? I want to know how the normal and considered correct way to do this is.
Thank you for reading.
I think the easiest way to achieve is this is the following:
map every node (e.g. represented by string) to an integer
store this mapping in a class representing the Graph object
instead of storing an array of ints, store an std::vector<std::vector<int>>
Now when you add something, the process becomes very straightforward:
add the new node to the mapping, its corresponding integer is the size of the adjecency matrix std::vector<std::vector<int>>
add a new std::vector<int> to the adjecency matrix, filled with zeros
updating the adjecency matrix is easy:
public void setAdjMat(const std::string& n0, const std::string& n1, int c){
int i0 = nodeMap[n0];
int i1 = nodeMap[n1];
adjecencyMatrix[i0][i1] = c;
}
The advantages:
adding requires very little effort, and does not need to restructure the entire adjecency matrix
removal can be implemented in two ways; removal from nodeMap and/or removal from adjecencyMatrix
for(int i=0; i < n; ++i){
//Find the leading element in a+M*i
if(!find_leading_element((a+M*i),n-i,m,&rowLead,&columnLead)){
return;
}
//Get the dividable from a[rowLEad][columnLead]
divide = (double)1/a[rowLead][columnLead];
printf("The divide from current matrix is %d\n\n",divide);
//Swap the current row = i with rowLead in matrix a+M*i
swap_rows((a+M*i),n-i,m,i,rowLead);
}
I am working on a small school project for reducing matrices but having some troubles passing the 2D array with an offset.
I need the find_leading_element to get a 2D array and return via the pointers the row and column of the leading element in that matrix.
Therefore find_leading_element returns the row and col relative to the matrix it got, and it is okay I will handle it later on. Now the issue is with passing the 2D array with a row offset.
So with each iteration I will pass the matrix but with one row less. Since I can't change the declaration for find_leading_element, I need to pass the function with double a[][M], does it mean it is passed by value?
bool find_leading_element(double a[][M], int n, int m, int * row, int * column) {
printf("In Find Leader got the matrix\n");
print_matrix((double (*)[M])a,n,m);
for(int i=0; i < m; ++i){
for(int j=0; j < n; ++j){
if(*(&a[0][0]+j*M+i) != 0){
*row = j;
*column = i;
return true;
}
}
}
return false;
}
double a[N][M];
printf("Enter matrix:\n");
if (!read_matrix((double (*)[M]) a, n, m)) {
printf("Invalid matrix!\n");
return ERROR;
}
What is the best way to do it? The way I do it here it only receives on the second iteration one row.
Beware pointer arithmetics is not raw addresses arithmetics.
As a is a 2D array declared as double a[N][M]; it will decay to a pointer to a row. That means that the address of the i-th row is a+i and not a+M*i.
The latter is used when you simulate a 2D array with a 1D one: int aa[N*M];. Here aa will decay to an int pointer and the beginning of the i-th row would be at aa+M*i.
The call should be:
//Find the leading element in a+M*i
if(!find_leading_element((a+i),n-i,m,&rowLead,&columnLead)){
return;
}
I am writing a piece of code that uses a struct containing a 2d array and predetermined functions which I have listed with comments describing what the function does.
struct matrix
{
char name;
int mValues[10][10[;
int nrows;
int ncols;
};
/** Function Prototypes**/
// Lets user name, choose dimensions and populates matrix from a 10x10 .txt file
void matrixInput(struct matrix *matA);
// Asks the user to choose how many rows to delete and select which rows
// Asks the user to choose how many columns to delete and select which columns.
// The result should be a sub matrix of the input matrix stored in a new struct matrix
void subMatrix(struct matrix m1, struct matrix *m2);
// What the Input/Output should look like
How many rows do you want to delete? : 2
Please enter, one per row, the number(s) of the 2 rows you want to delete : 2
Please enter, one per row, the number(s) of the 2 rows you want to delete : 1
How many columns do you want to delete? : 3
Please enter, one per column, the number(s) of the 3 columns you want to delete : 4
Please enter, one per column, the number(s) of the 3 columns you want to delete : 2
Please enter, one per column, the number(s) of the 3 columns you want to delete : 5
// Displays sub matrix
It's the last function I am having problems with.
I know the size of the input matrix and I think that I need to some how tell the complier pass the values of the input matrix to the new struct matrix while excluding the value of the user input for row/col number to be deleted. I'm not sure if this could be done in a nested loop or if I would need other variables to store values.
I know how to read and pass values at a given index but I'm stuck for ideas when it comes to not reading and passing values at a given index.
Can anybody point me in the right direction?
Side note, any tips on how to improve the quality of my question is welcomed.
If you know which columns and rows to delete, and you are sure that the result is going to fit in the new matrix, then just do a nested loop and tell it to ignore a certain range of values.
But what you really want to do is create the new matrix inside the copying function and return it. If they are created dynamically you can ignore assignment of the columns or rows you are trying to copy in the same way (nested loops) and fit it exactly with the size you need.
You can't easily store delete information in a matrix, because matrix->values[0][0] could refer to either row or column. It's easier to declare to integers instead.
The function void subMatrix(struct matrix m1,...) is technically okay if you don't want to change m1, but this makes an extra copy of m1 which is not efficient. It's better to use void subMatrix(const struct matrix *source,...) instead.
You can also use dynamic allocation instead of fixed array of value[10][10]. Example:
struct matrix {
int **data;
int rows;
int cols;
};
void create(struct matrix *m, int rows, int cols)
{
m->rows = rows;
m->cols = cols;
m->data = malloc(rows * sizeof(int*));
for(int r = 0; r < rows; r++)
m->data[r] = malloc(sizeof(int) * cols);
}
void destroy(struct matrix *m)
{
for(int i = 0; i < m->rows; i++)
free(m->data[i]);
free(m->data);
}
void print(const struct matrix *m)
{
for(int r = 0; r < m->rows; r++)
{
for(int c = 0; c < m->cols; c++)
printf("%4d", m->data[r][c]);
printf("\n");
}
printf("\n");
}
void change(struct matrix *new, struct matrix *m, int *delete_rows, int *delete_cols)
{
int rows = 0;
for(int row = 0; row < m->rows; row++)
if(!delete_rows[row])
rows++;
int cols = 0;
for(int col = 0; col< m->cols; col++)
if(!delete_cols[col])
cols++;
create(new, rows, cols);
int next_row = 0;
for(int row = 0; row < m->rows; row++)
{
if(delete_rows[row]) continue;
int next_col = 0;
for(int col = 0; col < m->cols; col++)
{
if(delete_cols[col]) continue;
new->data[next_row][next_col] = m->data[row][col];
next_col++;
}
next_row++;
}
}
int main(void)
{
struct matrix m;
create(&m, 10, 10);
for(int r = 0; r < m.rows; r++)
for(int c = 0; c < m.rows; c++)
m.data[r][c] = r * 100 + c;
print(&m);
//get delete information
int delete_rows[10] = { 0 };
int delete_cols[10] = { 0 };
delete_rows[0] = 1;//delete row 0
delete_cols[7] = 1;//delete col 7
struct matrix new;
change(&new, &m, delete_rows, delete_cols);
print(&new);
destroy(&m);
destroy(&new);
return 0;
}
So I'm currently working on a program that implements Gauss-Jordan elimination on a 2D array (matrix) and I am currently having a bit of a stump just trying to get the first row to divide itself by the first pivot:
void Gauss(int i, int j, int size, int mat [size][size])
{
int x = 0;
for(int i = 0; i < size;i++) {
for(int j = 0; j < size; j++) {
if(mat[i][j]== mat[i][i]) {
mat[0][i] = mat[0][i]/mat[i][i];
mat[i][i] = mat[i][i]/mat[i][i];
mat[i][j] = mat[i][i];
}
}
}
}
Here are is my original mat:
2 2 4
2 1 7
1 3 5
and here is my mat afterwards:
1 2 0
2 1 7
1 3 1
The program keeps dividing the first row by each of the diagonals. Can someone explain why this is occurring and a HINT as to how to fix it? Also, I don't have to worry about any of the pivots already being 0 because this is part of a much larger project that states it won't contain that.
Change this:
void Gauss(int i, int j, int size, int mat [i][j])
to this:
void Gauss(int i, int j, int size, int mat [size][size])
This mat[i][j] = mat[i][i]; has no usefulness, since it only gets executed when mat[i][j]== mat[i][i].
In this kind of applications, people usually use float and not int, but this is of course is not your direct error.