Transposing a matrix - c

I want to transpose a matrix, its a very easy task but its not working with me :
UPDATE
I am transposing the first matrix and
storing it in a second one
The two
arrays point to the same structure
I
need two arrays (target and source)
so I can display them later for
comparison.
struct testing{
int colmat1;
int rowmat1;
float mat[64][64];
};
int testtranspose(testing *test,testing *test2){
int i,j;
test2->colmat1 = test->rowmat1;
test2->rowmat1 = test->colmat1
for(i=0;i<test->rowmat1;i++){
for(j=0;j<test->colmat1;j++){
test2->mat[i][j] = test->mat[i][j];
}
printf("\n");
}
}
I thought this is the correct method of doing it, but apparently for a matrix such as :
1 2
3 4
5 6
7 8
I get :
1 2 0 0
3 4 0 0
What is the problem ?
Please help,
Thanks !

To transpose the matrix, you need to change rows and columns. So you need to use:
targetMatrix[i][j] = sourceMatrix[j][i];
Note how the order of i,j is changed, since one matrix's rows are another's columns.
By the way, instead of (*a).b, you can write a->b. This is the normal way of accessing a field of a struct pointer.

Try this...
struct testing{
int colmat;
int rowmat;
float mat[64][64];
};
int testtranspose(testing *test,testing *test2){
int i,j;
test2->colmat = test->rowmat;
test2->rowmat = test->colmat;
for(i=0;i<test->rowmat;i++){
for(j=0;j<test->colmat;j++){
test2->mat[j][i] = test->mat[i][j];
}
}
return 0;
}
int printmat(testing* mat)
{
for(int i=0;i<mat->rowmat;i++)
{
printf("\n");
for(int j=0;j<mat->colmat;j++)
printf((" %f"),mat->mat[i][j]);
}
return 0;
}
// 2
// main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
testing mat1, mat2;
memset(&mat1,0,sizeof(testing));
memset(&mat2,0,sizeof(testing));
mat1.colmat =2;
mat1.rowmat =3;
for(int i=0;i<mat1.rowmat;i++)
{
for(int j=0;j<mat1.colmat;j++)
mat1.mat[i][j] = (float)rand();
}
printmat(&mat1);
testtranspose(&mat1,&mat2);
printmat(&mat2);
getchar();
}

I am new to C / C++ (3rd day or so :) ) and I had the same problem. My approach was slightly different in that I thought it would be nice to have a function that would return a transposed matrix. Unfortunately, as I found out, you cannot return a an array nor pass an array to a function in C++ (let alone a double array), but you can pass / return a pointer which works similar to an array. So this is what I did:
int * matrix_transpose(int * A, int A_rows, int A_cols){
int * B;
int B_rows, B_cols;
B_rows = A_cols; B_cols= A_rows;
B = new int [B_rows*B_cols];
for(int i=0;i<B_rows;i++){
for(int j=0;j<B_cols;j++){
B[i*B_cols+j]=A[j*A_cols+i];
}
}
return B;
};
The trick was in dynamic arrays. I used A_rows and B_rows as separate names (you can use only rows and cols) in order to make the problem less intricate and less confusing when reading code.
B = new int [rows*cols] // This is cool in C++.

Related

A function in C runs for a set of values but gives Segmentation Fault: 11 for another

I am trying to find unique non-zero intersection between two sets. I have written a program which works for some set of arrays but gives segmentation fault for some. I have been trying to figure out why but have failed, any help will be greatly valued. The thing is the functions defined (NoRep and ComEle) are working fine but are unable to return the value to the assigned pointer in the case when Seg Fault is shown. Below is the code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int* ComEle(int ar_1[], int size_ar1, int ar_2[], int size_ar2);
int* NoRep(int a[], int l1);
int main ()
{
// Case 1: Gives segmentation fault
int A[10] = {1,1,0,2,2,0,1,1,1,0};
int B[10] = {1,1,1,1,0,1,1,0,4,0};
int *C = ComEle(A,10,B,10); printf("check complete\n");
// //Case 2: Does not give segmentation fault
// int A[4] = {2,3,4,5};
// int B[4] = {1,2,3,4};
// int *C = ComEle(A,4,B,4); printf("check complete\n");
}
//---------------- Local Functions --------------------//
int* ComEle(int ar_1[], int size_ar1, int ar_2[], int size_ar2) {
// sort of intersection of two arrays but only for nonzero elements.
int i=0, j=0, cnt1 = 0;
int temp1 = size_ar1+size_ar2;
int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
/* Size of CE1 is knowingly made big enough to accommodate repeating
common elements which can expand the size of resultant array to
values bigger than those for the individual arrays themselves! */
for(i=0;i<size_ar1;i++) {
j = 0;
while(j<size_ar2) {
if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
CE1[cnt1] = ar_1[i];
cnt1++;
}
j++;
}
}
// Have to remove repeating elements.
int *CE = NoRep(CE1, cnt1);
for(i=0;i<(CE[0]+1);i++) {printf("CE:\t%d\n", CE[i]);}
printf("ComEle: %p\n",CE);
return(CE);
}
int* NoRep(int a[], int l1) {
int cnt = 0, i = 0, j =0;
int *NR; NR = (int*)calloc((l1), sizeof(int));
//int NR[l1]; for(i=0;i<l1;i++) {NR[i] = 0;}
for(i=0;i<l1;i++) {
j = 0;
while(j<i) {
if(a[i]==a[j]) {break;}
j++;
}
if(j == i) {
cnt++;
NR[cnt] = a[i];
}
}
NR[0] = cnt; // First element: # of relevant elements.
printf("NoRep: %p\n",NR);
return(NR);
}
Thanks again for your help!
Take a look at this code:
int temp1 = size_ar1+size_ar2;
int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
/* Size of CE1 is knowingly made big enough to accommodate repeating
common elements which can expand the size of resultant array to
values bigger than those for the individual arrays themselves! */
for(i=0;i<size_ar1;i++) {
j = 0;
while(j<size_ar2) {
if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
CE1[cnt1] = ar_1[i];
cnt1++;
}
j++;
}
}
Here you have nested loops, i.e. a for-loop with a while-loop inside. So - in worst case - how many times can cnt1 be incremented?
The answer is size_ar1 * size_ar2
But your code only reserve size_ar1 + size_ar2 element for CE1. So you may end up writing outside the array.
You can see this very easy by printing cnt1 inside the loop.
In other words - your CE1 is too small. It should be:
int temp1 = size_ar1*size_ar2; // NOTICE: * instead of +
int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
But be careful here - if the input arrays are big, the VLA gets huge and you may run in to stack overflow. Consider dynamic memory allocation instead of an array.
Besides the accepted answer: I have been missing a break statement in the while loop in ComEle function. It was not giving me the expected value of cnt1. The following will be the correct way to do it:
for(i=0;i<size_ar1;i++) {
j = 0;
while(j<size_ar2) {
if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
CE1[cnt1] = ar_1[i];
cnt1++;
break;
}
j++;
}
}
This will also do away with the requirement for a bigger array or dynamic allocation as suggested (and rightly so) by #4386427

Changing the contents of an array in a recursive function

I am having trouble understanding something regarding recursion and arrays.
basically, what the program does is to check what is the maximum weights of items that can be placed in two boxes. I know it's far from perfect as it is right now, but this is not the point.
Generally everything is working properly, however, now I decided that I want to see the contents of each box when the weight is maximal. For this purpose I tried using arr1 and arr2.
I don't understand why I get different results for arr1 and arr2 (the first options gives me what I want, the second does not).
This is the program:
#define N 5
int help(int items[N][2], int box1[N], int box2[N], int rules[N][N],
int optimal,int current_weight,int item,int arr1[],int arr2[])
{
if (item == N)
{
if(current_weight>optimal) //This is the first option
{
memcpy(arr1,box1,sizeof(int)*N);
memcpy(arr2,box2,sizeof(int)*N);
}
return current_weight;
}
int k = items[item][1]; int sol;
for (int i = 0; i <= k; i++)
{
for (int j = 0; i+j <= k; j++)
{
box1[item] += i; box2[item] += j;
if (islegal(items, box1, box2, rules))
{
sol = help(items, box1, box2, rules, optimal,
current_weight + (i + j)*items[item][0],item+1,arr1,arr2);
if (sol > optimal)
{
optimal = sol;
memcpy(arr1,box1,sizeof(int)*N); //This is the second option
memcpy(arr2,box2,sizeof(int)*N);
}
}
box1[item] -= i; box2[item] -= j;
}
}
return optimal;
}
int insert(int items[N][2], int rules[N][N])
{
int box1[N] = { 0 }; int arr1[N] = { 0 };
int box2[N] = { 0 }; int arr2[N] = { 0 };
int optimal = 0;
int x = help(items, box1, box2, rules,0, 0,0,arr1,arr2);
print(arr1, N);
print(arr2, N);
return x;
}
Can anyone explain what causes the difference? Why the first option is correct and the second is not? I couldn't figure it out by my own.
Thanks a lot.
This doesn't work because when you pass box1 and box2 to help, they are mutated by help. It's pretty obvious from the algorithm that you want them to not be mutated. So, we can do as follows:
int help(int items[N][2], int box1in[N], int box2in[N], int rules[N][N],
int optimal,int current_weight,int item,int arr1[],int arr2[])
{
int box1[N];
int box2[N];
memcpy(box1, box1in, sizeof(int)*N);
memcpy(box2, box2in, sizeof(int)*N);
Your algorithm may still have problems but that problem is now removed.

C data format redoing

I have data stored as
float testdata3[][7] = {
{171032, 0.4448, -0.3032, -0.7655, -1.3428, 13.5803, -73.0743},
{172292, 0.0099, 0.1470, -0.7301, -17.2272, 7.0038, -11.7722},
{173547, 0.0576, 0.1333, -0.8163, -2.7847, -9.5215, 8.1177 },
...
}
where I am only interested in the second, third and fourth indexes. How can I create a function where it would return for example first, second and third index as their own table from the testdata I have.
For example
testdata_x = {0.4448, 0.099, 0.0576, ...}
testdata_y = {-0.3032, 0.1470, 0.1333, ...}
testdata_z = {-0.7655, -0.7301, -0.8163, ...}
Help would be much appreciated. I am trying to read sensor values from test data and im only interested in acceleration values in x, y and z directions.
You didn't post any code so I'm going to be a bit more vague than normal.
If we create an array of 7 elements such as: int arr[7] = {1, 2, 3, 4, 5, 6, 7};
Accessing the 2nd, third, and 4th elements is as simple as arr[1], arr[2], arr[3] respectively.
That should help with gleaning the data from the existing arrays, but as for making your new array. I don't see any reason to use a multidimensional array instead of 3 regular arrays. All you need to do from here is find out the amount of arrays in testData in order to know how much to allocate and you should be on your way.
So you want to transpose a matrix? then just iterate in the reverse order
#include <stdio.h>
int main(void)
{
double arr[][7] = {
{171032, 0.4448, -0.3032, -0.7655, -1.3428, 13.5803, -73.0743},
{172292, 0.0099, 0.1470, -0.7301, -17.2272, 7.0038, -11.7722},
{173547, 0.0576, 0.1333, -0.8163, -2.7847, -9.5215, 8.1177},
};
#define ROWS sizeof arr / sizeof arr[0]
#define COLS sizeof arr[0] / sizeof arr[0][0]
double test[COLS][ROWS]; /* 7 x 3 */
for (size_t i = 0; i < COLS; i++) {
for (size_t j = 0; j < ROWS; j++) {
test[i][j] = arr[j][i];
}
}
return 0;
}
I don't know what you are looking for but here are several approaches starting from easiest one:
1) You can directly assign a value using indexes to the new array
2) If you need function you can allocate new array inside it assign all
values and return it from a function
It's supposed that indexes never change for x,y,z.
#include <stdio.h>
#include <stdlib.h>
enum
{
X,
Y,
Z
};
float testdata3[][7] = {
{171032, 0.4448, -0.3032, -0.7655, -1.3428, 13.5803, -73.0743},
{172292, 0.0099, 0.1470, -0.7301, -17.2272, 7.0038, -11.7722},
{173547, 0.0576, 0.1333, -0.8163, -2.7847, -9.5215, 8.1177 },
};
float *get_dataa(int coordinate)
{
float *data;
switch(coordinate) {
case X:
data = malloc(sizeof(float) * 3);
data[0] = testdata3[0][1];
data[1] = testdata3[1][1];
data[2] = testdata3[2][1];
return data;
default:
return NULL;
}
}
int main(void)
{
/* first way */
float testdata_X[] = { testdata3[0][1], testdata3[1][1], testdata3[2][1] };
printf("Test number 1 for X %0.4f, %0.4f, %0.4f\n", testdata_X[0], testdata_X[1], testdata_X[2]);
/* second */
float *testdata_xX = get_dataa(X);
printf("Test number 2 for X %0.4f, %0.4f, %0.4f\n", testdata_xX[0], testdata_xX[1], testdata_xX[2]);
free(testdata_xX);
return 0;
}
output:
Test number 1 for X 0.4448, 0.0099, 0.0576
Test number 2 for X 0.4448, 0.0099, 0.0576

Getting the values of linked list with loops

I have to create a function who can get the value of a matrix wich take the form of a double linked list. Here is the structures of the matrix
typedef struct row {
unsigned int indiceRow;
struct row * next;
struct col * data;
} row;
typedef struct col{
double value;
unsigned int indiceColumn;
struct col * next;
} col;
typedef struct matrix{
int nRows;
int nCols;
struct row * rowFirst;
}matrix;
the structure matrix represent the top of the linked list and contain the total number of rows and columns and a variable row wich point to the first node of the list of row nodes. the row nodes contain the number of the row of the matrice, a variable row called next wich represent the next line of the matrix and a variable data point to another list of col nodes. Those col nodes contains the number of the column, the value at those coordonates(row,column) and the a col next. only the values different of zero have to be in the col linked list.
To get the value of a precise point of the matrix I created the function sp_get. It take a structure matrix, the line and column I'm looking for and a double variable as argument. It returns 0 when it works and update the variable double *val with the value I'm looking for.
int sp_get( struct matrix *mat, unsigned int rows, unsigned int col, double *val){
row * temps = (row*)malloc(sizeof(row));
temps = mat->rowFirst;
while(temps->indiceRow!= rows){
temps = temps->next;
}
while(temps->data!= NULL && temps->data->indiceColumn!= col && temps->data->next!=NULL){
temps->data = temps->data->next;
}
if(temps->data->indiceColumn == col){
*(val) = temps->data->value;
}
else{
*(val) = 0.0;
}
return 0;
First I create a row variable to run through the matrix, then I look for the good row and then for the good column. If I can't find the good column it means that the value is 0.
When I use the function to look for one value, it works well, and always return the good value.(tempMatrix is a matrix variable and contain the linked list)
double * vall =(double*)malloc(sizeof(double));
sp_get(tempMatrix, 2, 3, vall);
but when I'm using the function with a double loop for I don't have the same results and I can't not explain why...
double * vall =(double*)malloc(sizeof(double));
int i;
int j;
for(i=1;i<=tempMatrix->nRows;i++){
for(j=1; j<=tempMatrix->nCols;j++){
sp_get(tempMatrix,i,j,vall);
printf(" %f ", *(vall));
}
printf("\n");
}
Here are the result I get with the loops
and here are the results I should get
It might be a proble of memory leak, I don't know where it comes from.
Thanks in advance for your help!
Just in sp_get alone the following problems abound:
Memory the first two lines.
Anytime you see something like this in successive lines in C:
ptr = malloc(...)
ptr = <something else>
it is always a memory leak.
Updating the column header rather than simply enumerating it
Once you find the row you seek, you then do this:
while(temps->data!= NULL &&
temps->data->indiceColumn!= col &&
temps->data->next!=NULL)
{
temps->data = temps->data->next;
}
Ask yourself, what is temps->data = ... actually updating? It is changing the temps->data pointer to point to its own next, which means what temps->data pointed to prior is gone. That's fine if temps->data is a temporary pointer, but it isn't. It is the data member in the row struct you worked so hard to find in the prior loop.
Potential NULL pointer dereference
You may think having this:
while(temps->data!= NULL &&
temps->data->indiceColumn!= col &&
temps->data->next!=NULL)
for the while-condition in your loop will harbor safety from temp-data being NULL for the code that follows:
if(temps->data->indiceColumn == col)
{
*(val) = temps->data->value;
}
but if it did, then why bother with the first clause (which is correct, btw). It appears the addition of the last clause (temps->data->next!=NULL) was an effort to stave off crashes. That isn't the way to do it.
Minor: Hiding type col with parameter col
Needs little explanation. See your var names.
Minor: There is no need to dynamically allocate the out-parameter as you're using it.
Your code do to this:
double * vall =(double*)malloc(sizeof(double));
int i, j;
for(i=1;i<=tempMatrix->nRows;i++)
{
for(j=1; j<=tempMatrix->nCols;j++)
{
sp_get(tempMatrix,i,j,vall);
printf(" %f ", *(vall));
}
printf("\n");
}
Can just as easily do this:
double val = 0.0;
int i, j;
for(i=1;i<=tempMatrix->nRows;i++)
{
for(j=1; j<=tempMatrix->nCols;j++)
{
sp_get(tempMatrix,i,j,&val); // note address-of operator
printf(" %f ", val);
}
printf("\n");
}
Updated sp_get
I'm pretty sure this is what you're trying to do. The following will return 0 if the indexed values found and retrieved, otherwise it returns -1 and the out-parameter is set to 0.0.
int sp_get( struct matrix const *mat, unsigned int rows, unsigned int cols, double *val)
{
// prime to 0.0
*val = 0.0;
if (!mats)
return -1;
// walk the row table
struct row const *row_ptr = mat->rowFirst;
while (row_ptr && row_ptr->indiceRow != rows)
row_ptr = row_ptr->next;
// leave now if we didn't find the row.
if (!row_ptr)
return -1;
struct col const *col_ptr = row_ptr->data;
while (col_ptr && col_ptr->indiceColumn != cols)
col_ptr = col_ptr->next;
if (!col_ptr)
return -1;
*val = col_ptr->value;
return 0;
}
Note we modify nothing in the actual matrix, so the entire thing, including all pointers we use to index within it, can be const (and should be).
Best of luck.

How to find which value is closest to a number in C?

I have the following code in C:
#define CONST 1200
int a = 900;
int b = 1050;
int c = 1400;
if (A_CLOSEST_TO_CONST) {
// do something
}
What is a convenient way to check whether if a is the closest value to CONST among a,b and c ?
Edit:
It doesn't matter if I have 3 variables or an array like this (it could be more than 3 elements):
int values[3] = {900, 1050, 1400};
This works for three variables:
if (abs(a - CONST) <= abs(b - CONST) && abs(a - CONST) <= abs(c - CONST)) {
// a is the closest
}
This works with an array of one or more elements, where n is the number of elements:
int is_first_closest(int values[], int n) {
int dist = abs(values[0] - CONST);
for (int i = 1; i < n; ++i) {
if (abs(values[i] - CONST) < dist) {
return 0;
}
}
return 1;
}
See it working online: ideone
Compare the absolute value of (a-CONST), (b-CONST) and (c-CONST). Whichever absolute value is lowest, that one is closest.
Here is a generalized method. The min_element() function takes an int array, array size, and pointer to a comparison function. The comparison predicate returns true if the first values is less than the second value. A function that just returned a < b would find the smallest element in the array. The pinouchon() comparison predicate performs your closeness comparison.
#include <stdio.h>
#include <stdlib.h>
#define CONST 1200
int pinouchon(int a, int b)
{
return abs(a - CONST) < abs(b - CONST);
}
int min_element(const int *arr, int size, int(*pred)(int, int))
{
int i, found = arr[0];
for (i = 1; i < size; ++i)
{
if (pred(arr[i], found)) found = arr[i];
}
return found;
}
int main()
{
int values[3] = {900, 1050, 1400};
printf("%d\n", min_element(values, 3, pinouchon));
return 0;
}
I m adding something in Mark Byres code.....
int is_first_closest(int values[]) {
int dist = abs(values[0] - CONST),closest; //calculaing first difference
int size = sizeof( values ) //calculating the size of array
for (int i = 1; i < size; ++i) {
if (abs(values[i] - CONST) < dist) { //checking for closest value
dist=abs(values[i] - CONST); //saving closest value in dist
closest=i; //saving the position of the closest value
}
}
return values[i];
}
This function will take an array of integers and return the number which is closest to the CONST.
You need to compare your constant to every element. (works well for 3 elements but it's a very bad solution for bigger elementcount, in which case i suggest using some sort of divide and conquer method). After you compare it, take their differences, the lowest difference is the one that the const is closest to)
This answer is a reaction to your edit of the original question and your comment.
(Notice that to determine the end of array we could use different approaches, the one i shall use in this particular scenario is the simplest one.)
// I think you need to include math.h for abs() or just implement it yourself.
// The code doesn't deal with duplicates.
// Haven't tried it so there might be a bug lurking somewhere in it.
const int ArraySize = <your array size>;
const int YourConstant = <your constant>;
int values[ArraySize] = { ... <your numbers> ... };
int tempMinimum = abs(YourArray[0] - YourConstant); // The simplest way
for (int i = 1; i < ArraySize; i++) { // Begin with iteration i = 1 since you have your 0th difference computed already.
if (abs(YourArray[i] - YourConstant) < tempMinumum) {
tempMinumum = abs(YourArray[i] - YourConstant);
}
}
// Crude linear approach, not the most efficient.
For a large sorted set, you should be able to use a binary search to find the two numbers which (modulo edge cases) border the number, one of those has to be the closest.
So you would be able to achieve O(Log n) performance instead of O(n).
pseudocode:
closest_value := NULL
closest_distance := MAX_NUMBER
for(value_in_list)
distance := abs(value_in_list - CONST)
if (distance < closest_distance)
closest_value := value_in_list
closest_distance := distance
print closest_value, closest_distance

Resources