matrix multiplication using malloc without user input - matrix

I am trying to use Malloc function to dynamically allocate memory but I also want to specify my data entry for operation rather than taking the user input.
I have found this code here which works fine, but I am working with a large data set and taking user input is not an option, so I want to keep using MALLOC but also define the data set.
like instead of following,
//Input Matrix1
for (i = 0; i < r1; i++)
for (j = 0; j < c1; j++)
scanf_s("%d", &mat1[i][j]);
I want something like
//mat1[2][2] = { {1,2},{2,3} }
to be inputed in the code
What would be the way to do it? I would really appreciate some advice. Thanks
#include<stdio.h>
#include<stdlib.h>
int main() {
int **mat1, **mat2, **res, i, j,k, r1, c1, r2, c2;
printf("\nEnter the Order of the First matrix...\n");
scanf_s("%d %d", &r1, &c1);
printf("\nEnter the Order of the Second matrix...\n");
scanf_s("%d %d", &r2, &c2);
if (c1 != r2) {
printf("Invalid Order of matrix");
exit(EXIT_SUCCESS);
}
mat1 = (int**)malloc(r1 * sizeof(int*));
for (i = 0; i < c1; i++)
mat1[i] = (int*)malloc(c1 * sizeof(int));
mat2 = (int**)malloc(r2 * sizeof(int*));
for (i = 0; i < c2; i++)
mat2[i] = (int*)malloc(c2 * sizeof(int));
res = (int**)calloc(r1, sizeof(int*));
for (i = 0; i < c2; i++)
res[i] = (int*)calloc(c2, sizeof(int));
/**/
//Input Matrix1
for (i = 0; i < r1; i++)
for (j = 0; j < c1; j++)
scanf_s("%d", &mat1[i][j]);
//Input Matrix2
for (i = 0; i < r2; i++)
for (j = 0; j < c2; j++)
scanf_s("%d", &mat2[i][j]);
//Printing Input Matrix 1 and 2
printf("\n Entered Matrix 1: \n");
for (i = 0; i < r1; i++) {
for (j = 0; j < c1; j++)
printf("%d ", mat1[i][j]);
printf("\n");
}
printf("\n Entered Matrix 2: \n");
for (i = 0; i < r2; i++) {
for (j = 0; j < c2; j++)
printf("%d ", mat2[i][j]);
printf("\n");
}
//int mat1[2][2] = { {1,2},{2,3} };
//int mat2[2][2] = { {1,3},{2,4} };
//Computation
//Multiplication
for (i = 0; i < r1; i++) {
for (j = 0; j < c2; j++) {
res[i][j] = 0;
for (k = 0; k < c1; k++)
res[i][j] += mat1[i][k] * mat2[k][j];
}
printf("\n");
}
printf("\nThe Multiplication of two matrix is\n");
for (i = 0; i < r1; i++) {
printf("\n");
for (j = 0; j < c2; j++)
printf("%d\t", res[i][j]);
}
printf("\n");
/* Addition
for(i=0;i<r1;i++)
for(j=0;j<c2;j++)
res[i][j]=mat1[i][j]+mat2[i][j];
printf("\nThe Addition of two matrix is\n");
for(i=0;i<r1;i++){
printf("\n");
for(j=0;j<c2;j++)
printf("%d\t",res[i][j]);
}
*/
return 0;
}

Please specify the format of your input data. Is it a csv file?
You can only specify data in the format int b[4] = {1, 2, 3, 4} when the size of b is fixed, i.e. known at compile time. But if all you matrices are known at compile time anyway, why bother doing dynamic allocation?
Also I cleaned up your code a bit:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define index(x, y, r) (x+r*y)
struct matrix {
int cols;
int rows;
double * data;
};
void print_mat(struct matrix * mat) {
int i, j;
for (i = 0; i < mat->rows; i++) {
for (j = 0; j < mat->cols; j++) {
printf("%f \t", mat->data[index(i, j, mat->rows)]);
}
printf("\n");
}
}
int mat_alloc(struct matrix *mat) {
mat->data = (double*)malloc(mat->rows*mat->cols*sizeof(double));
}
int read_mat(struct matrix *mat) {
int i, j;
for (i = 0; i < mat->rows; i++) {
for (j = 0; j < mat->cols; j++) {
scanf("%lf", &(mat->data[index(i, j, mat->rows)]));
}
}
}
int multiply(struct matrix * a, struct matrix * b, struct matrix * res) {
if(a->cols != b->rows){
printf("Matrix dimensions do not match!\n");
return 0;
}
res->rows = a->rows;
res->cols = b->cols;
mat_alloc(res);
memset(res->data, 0, res->cols*res->rows*sizeof(double));
int i, j, k;
for (i = 0; i < res->rows; i++) {
for (j = 0; j < res->cols; j++) {
for (k = 0; k < a->cols; k++) {
res->data[index(i, j, res->rows)] += a->data[index(i, k, a->rows)] * b->data[index(k, j, b->rows)];
}
}
}
}
int main() {
struct matrix mat1, mat2, res;
printf("\nEnter the Order of the First matrix...\n");
scanf("%d %d", &mat1.rows, &mat1.cols);
printf("\nEnter the Order of the Second matrix...\n");
scanf("%d %d", &mat2.rows, &mat2.cols);
mat_alloc(&mat1);
mat_alloc(&mat2);
read_mat(&mat1);
read_mat(&mat2);
printf("Scanned matrices: \n");
print_mat(&mat1);
printf("\n");
print_mat(&mat2);
printf("\n");
multiply(&mat1, &mat2, &res);
printf("Calculated result: \n");
print_mat(&res);
return 0;
}

Related

How to reconstruct the pixel on a specify cube?

Now I have a vtkImageData (WxHxS) .I want to recontruct the cube to SxHxW
I think there is a mapping for the goal
NEW ORIGIN
(i,0,0) ⇒ (W-i,0,0)
(0,j,0) ⇒ (W,j,0)
(0,0,k) ⇒ (W,0,k)
so I try to setting the new diminsion and extent for the vtkImageData
m->SetDimensions(S, H, W);
m->SetSpacing(origin->GetSpacing()[2], origin->GetSpacing()[1], origin->GetSpacing()[0]);
for (int k = 0; k < W; k++)
for (int j = 0; j < H; j++)
for (int i = 0; i< S; i++)
{
ptr = (unsigned short *)m->GetScalarPointer(i, j, k);
ori = (unsigned short *)origin->GetScalarPointer(W - 1 - k, j, S -1- i);
*ptr = *ori;
}
//But it doesn't get the matter
//However, when I use the pixel method to copy origin data or upsidedow data, it is correct //like below
//copy the same structure
for (int k = 0; k < S; k++)
for (int j = 0; j < H; j++)
for (int i = 0; i< W; i++)
{
ori = (unsigned short*)origin->GetScalarPointer(i, j, k);
ptr = (unsigned short*)m->GetScalarPointer(i, j, k);
*ptr = *ori;
}
//upsiaedown
double val; int i = 0;
for (vtkIdType f = m->GetNumberOfPoints() - 1; f > -1; f--)
{
val =m->GetPointData()->GetScalars()->GetTuple1(f);
origin->GetPointData()->GetScalars()->SetTuple1(i, val);
i++;
}
correct cubic output
Briefly speaking, I want to get a new vtkImageData which is rotate (alone specify axis)

Runtime error for large inputs for sorting ( quicksort)

This is a very simple program where the user inputs (x,y) coordinates and distance 'd' and the program has to find out the number of unrepeated coordinates from (x,y) to (x+d,y).
For eg: if input for one test case is: 4,9,2 then the unrepeated coordinates are (4,9),(5,9) and (6,9)(x=4,y=9,d=2). I have used a sorting algorithm as mentioned in the question (to keep track of multiple occurrences) however the program shows runtime error for test cases beyond 30. Is there any mistake in the code or is it an issue with my compiler?
For a detailed explanation of question: https://www.hackerearth.com/practice/algorithms/sorting/merge-sort/practice-problems/algorithm/missing-soldiers-december-easy-easy/
#include <stdio.h>
#include <stdlib.h>
int partition(int *arr, int p, int r) {
int x;
x = arr[r];
int tmp;
int i = p - 1;
for (int j = p; j <= r - 1; ++j) {
if (arr[j] <= x) {
i = i + 1;
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
tmp = arr[i + 1];
arr[i + 1] = arr[r];
arr[r] = tmp;
return (i + 1);
}
void quicksort(int *arr, int p, int r) {
int q;
if (p < r) {
q = partition(arr, p, r);
quicksort(arr, p, q - 1);
quicksort(arr, q + 1, r);
}
}
int count(int A[],int ct) {
int cnt = 0;
for (int i = 0; i < ct; ++i) {
if (A[i] != A[i + 1]) {
cnt++;
}
}
return cnt;
}
int main() {
int t;
scanf("%d", &t);
long int tmp, y, d;
int ct = 0;
int i = 0;
int x[1000];
int j = 0;
for (int l = 0; l < t; ++l) {
scanf("%d%d%d", &tmp, &y, &d);
ct = ct + d + 1; //this counts the total no of coordinates for each (x,y,d)
for (int i = 0; i <= d; ++i) {
x[j] = tmp + i; //storing all possible the x and x+d coordinates
j++;
}
}
int cnt;
int p = ct - 1;
quicksort(x, 0, p); //quicksort sorting
for (int l = 0; l < ct; ++l) {
printf("%d ", x[l]); //prints sorted array not necessary to question
}
cnt = count(x, ct); //counts the number of non-repeated vertices
printf("%d\n", cnt);
}
The problem was the bounds of the array int x[1000] is not enough for the data given below.

Thrust's exclusive_scan_by_key function takes the same amount of time as a sequential implementation?

I'm relatively new to Thrust and I'm trying to perform a segmented scan. Here is my code, which you should be able to run as-is:
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/execution_policy.h>
#include <chrono>
// Sequential scan for CPU
float* test_seqScan(float* in, int s, int m) {
float* out = new float[s * m];
for (unsigned int i = 0; i < s; i++) {
out[i * m] = 0;
}
for (unsigned int i = 0; i < s; i++) {
for (unsigned int j = 1; j < m; j++) {
out[i * m + j] = out[i * m + j - 1] + in[i * m + j - 1];
}
}
return out;
}
void test_sumScan(thrust::device_vector<float> dev_in, thrust::device_vector<int> dev_keys, int s, int m) {
// Allocate device memory for output
thrust::device_vector<float> dev_out(s * m);
thrust::exclusive_scan_by_key(thrust::device, dev_keys.begin(), dev_keys.end(), dev_in.begin(), dev_out.begin());
}
int main(){
int s = 100;
int m = 100000;
float* seq_in = new float[s * m];
for (int i = 0; i < s; i++) {
for (int j = 0; j < m; j++) {
seq_in[i * m + j] = j + 1;
}
}
thrust::host_vector<float> par_in(s * m);
for (int i = 0; i < s; i++) {
for (int j = 0; j < m; j++) {
par_in[i * m + j] = j + 1;
}
}
thrust::host_vector<int> keys(s * m);
for (int i = 0; i < s; i++) {
for (int j = 0; j < m; j++) {
keys[i * m + j] = i;
}
}
thrust::device_vector<float> dev_in = par_in;
thrust::device_vector<int> dev_keys = keys;
auto t1 = std::chrono::high_resolution_clock::now();
test_seqScan(seq_in, s, m);
auto t2 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
std::cout << "Sequential duration: " << duration1 << "\n\n";
auto t3 = std::chrono::high_resolution_clock::now();
test_sumScan(dev_in, dev_keys, s, m);
auto t4 = std::chrono::high_resolution_clock::now();
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
std::cout << "Parallel duration: " << duration2 << "\n\n";
}
My issue is that both these snippets of code take exactly the same amount of time to run regardless of how small or large I set s and m. I assume that I'm doing something wrong, but I don't know what; can anyone point out the issue?

Code just loads for a second, then closes without doing anything

For some reason, whenever I run this code, it just opens; loads for a sec; then closes without doing anything. Whenever I try to narrow it down to a piece of code, it makes absolutely no sense, like the line int dirX.
#include <iostream>
#include <queue>
using namespace std;
void solve()
{
// ENTER CODE BELOW
struct Loc
{
int x, y;
Loc (int xx=0, int yy=0) : x(xx), y(yy) {}
};
int n=0, currX=1002, currY=1002, dx[]={-1,1,0,0},dy[]={0,0,-1,1}; string str=""; bool isFence[2010][2010]; queue<Loc> q;
int ret=-1;
for (int i = 0; i < 2005; i++) {
for (int j = 0; j < 2005; j++) {
isFence[i][j]=false;
}
}
cin >> n >> str;
isFence[currX][currY]=true;
int dirX, dirY;
for (auto i : str)
{
dirX=0; dirY=0;
if (i=='N') dirX=-1;
else if (i=='S') dirX=1;
else if (i=='W') dirY=-1;
else dirY=1;
for (int j = 0; j < 2; j++) {
currX += dirX;
currY += dirY;
isFence[currX][currY]=true;
}
}
Loc curr; int nx, ny;
for (int i = 0; i < 2005; i++)
{
for (int j = 0; j < 2005; j++)
{
cout << isFence[i][j] << endl;
if (isFence[i][j]) continue;
ret++;
q = std::queue<Loc>();
q.push(Loc(i,j));
isFence[i][j]=true;
while (!q.empty())
{
curr = q.front(); q.pop();
for (int k = 0; k < 4; k++) {
nx = curr.x+dx[k]; ny=curr.y+dy[k];
if (nx >= 0 && nx < 2005 && ny >= 0 && ny<2005 && !isFence[nx][ny]) {
isFence[nx][ny]=true;
q.push(Loc(nx, ny));
}
}
}
}
}
cout << ret;
// ENTER CODE ABOVE
}
int main()
{
solve();
}
Also, the reason I have all my code in the solve() function was because this is an assignment and I have to do it this way.
Sidenote: I wrote this code very quickly, so it's very badly formatted.

Schedule round robin matches

How to implement a round robin schedule for an array of 4 elements [1,2,3,4]? The result of the algorithm should be able to display, for each element, the list of the players it will face in chronological order:
(1: 4,2,3)
(2: 3,1,4)
(3: 2,4,1)
(4: 1,3,2)
Line 1: 4,2,3 means that the player (1) will face in order the players (4), (2) and (3).
Of the same way, line 2: 3,1,4 indicates that the player (2) will face in order the players (3), (1) and (2).
We have implemented this code but we encounter a bug when we start filling in the name of the player. Do you have any idea about this problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_MAX_LENGTH 20
#define NUM_MIN_PLAYERS 2
#define NUM_MAX_PLAYERS 20
enum Style
{
STYLE_COMPACT,
STYLE_TABLE
};
enum Format
{
FORMAT_ID,
FORMAT_NAME
};
struct PlayerList
{
unsigned int num_players;
char name[NUM_MAX_PLAYERS][NAME_MAX_LENGTH + 1];
};
struct Grid
{
unsigned int num_players;
unsigned int day[NUM_MAX_PLAYERS]
[NUM_MAX_PLAYERS];
};
void printList(struct PlayerList *list)
{
for (int i = 0; i < list->num_players; i++)
{
printf("%d:%s\n", i + 1, list->name[i]);
}
}
struct Grid calculer_berger(struct PlayerList *list)
{
struct Grid grid;
// algo pour remplir la grid
grid.num_players = list->num_players;
int i, j;
for (i = 0; i < list->num_players - 1; i++)
{
for (j = 0; j < list->num_players - 1; j++)
{
if (i == j)
{
/* edge cases */
grid.day[i][list->num_players - 1] = ((i + j) + (i + j) / list->num_players) % list->num_players;
grid.day[list->num_players - 1][j] = ((i + j) + (i + j) / list->num_players) % list->num_players;
grid.day[i][j] = 0;
}
else
{
grid.day[i][j] = ((i + j) + (i + j) / list->num_players) % list->num_players;
}
}
}
grid.day[0][list->num_players - 1] = list->num_players - 1;
grid.day[list->num_players - 1][list->num_players - 1] = 0;
grid.day[list->num_players - 1][0] = list->num_players - 1;
return grid;
}
void permuter(struct Grid *grid)
{
int tmp;
for (int i = 0; i < grid->num_players; i++)
{
for (int j = 1; j <= grid->num_players / 2; j++)
{
tmp = grid->day[i][j];
grid->day[i][j] = grid->day[i][grid->num_players - j];
grid->day[i][grid->num_players - j] = tmp;
}
}
}
void print_grid(struct Grid *grid, struct PlayerList *list)
{
for (int i = 0; i < grid->num_players; i++)
{
for (int j = 0; j < grid->num_players; j++)
{
if (j == 0)
{
printf("%d:", grid->day[i][j] + 1);
}
else
{
printf("%d", grid->day[i][j] + 1);
if (j < grid->num_players - 1)
{
printf(",");
}
}
}
printf("\n");
}
}
int main(int argc, char **argv)
{
struct PlayerList playerList;
char nom[NAME_MAX_LENGTH + 1];
int nbCharLu = 0;
while ((nbCharLu = fscanf(stdin, "%s", nom)) != -1)
{
strcpy(playerList.name[playerList.num_players], nom);
playerList.num_players++;
}
struct Grid myGrid = calculer_berger(&playerList);
printList(&playerList);
print_grid(&myGrid, &playerList);
printf("Apres la permut\n");
permuter(&myGrid);
print_grid(&myGrid, &playerList);
return 0;
}
Assuming you are storing the elements in an Integer array and that you would like to just display the results.
Here is one implementation....The code should accommodate "N" values because of the use of "sizeof"....
feel free to customize it further....
#include <stdio.h>
int main() {
int i,j;
int array[] = {1,2,3,4};
for(i = 0; i < sizeof(array)/sizeof(int);++i){
printf("(%d :",array[i]);
for(j = 0; j < sizeof(array)/sizeof(int);++j){
if(j == i)
continue;
printf("%d ",array[j]);
}
printf(")\n");
}
}
#include <stdio.h>
void main() {
int mid;
int num;
int j, temp;
int k = 0;
int num1;
int data[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
num = sizeof(data)/sizeof(int);
mid = (sizeof(data)/sizeof(int))/2;
while(k < num - 1){
printf("Round %d ( ",k+1);
num1 = num;
for(int i = 0;i < mid;i++,num1--) /*pairing the competitors in each round*/
printf("%d:%d ",data[i],data[num1-1]);
for(int i = 0,j = num-1; i < num -2;i++,j--){ /* fixing the first competitor and rotating the others clockwise*/
temp = data[j];
data[j] = data[j-1];
data[j-1] = temp;
}
printf(")\n");
k++;
}
}

Resources