I am trying to implement Sequence alignment problem (Needleman-Wunsch algorithm) using p-Threads. I am confused how to map the concept of multi threading in this particular serial problem. The code of serial computation of sequence alignment is enclosed below.(Just Matrix calculation part)
#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std;
class Matrix
{
private:
int x;
int y;
int** mat;
string gene1;
string gene2;
int match_penalty;
int mismatch_penalty;
int gap_penalty;
int minimum_penalty;
public:
Matrix(int gene1Len, int gene2Len)
{
x = gene2Len + 1; //gene2 length
y = gene1Len + 1; //gene 1 length;
mat = new int* [x];
for (int i = 0; i < x; i++)
mat[i] = new int[y];
for (int i = 0; i < x; ++i) {
for (int j = 0; j < y; ++j) {
mat[i][j] = 0;
}
}
//Default Penalties
match_penalty = 1;
mismatch_penalty = 3;
gap_penalty = 2;
minimum_penalty=0;
}
void Print_Matrix()
{
cout<<"\n";
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
cout << mat[i][j] << "\t";
}
cout << "\n";
}
}
void setGenes(string gene1, string gene2)
{
this->gene1 = gene1;
this->gene2 = gene2;
}
void setPenalty(int mismatch, int gp,int match)
{
mismatch_penalty = mismatch;
gap_penalty = gp;
match_penalty=match;
}
void setMatrix()
{
//1st row and 1st Column values
for (int i = 0; i < x; i++)
{
mat[i][0] = i * gap_penalty;
}
for (int i = 0; i < y; i++)
{
mat[0][i] = i * gap_penalty;
}
// Other matrix values
for (int i = 1; i < x; i++)
{
for (int j = 1; j < y; j++)
{
if (gene1[j - 1] == gene2[i - 1]) //Similar gene values (A==A ||T==T)
{
mat[i][j] = mat[i - 1][j - 1]+match_penalty;
}
else
{
mat[i][j] = max({ mat[i - 1][j - 1] + mismatch_penalty , mat[i - 1][j] + gap_penalty, mat[i][j - 1] + gap_penalty });
}
}
}
}
};
int main()
{
string gene1 = "ACCA";
string gene2 = "CCA";
int matchPenalty;
int misMatchPenalty ;
int gapPenalty ;
cout<<"Enter the value of Match Penalty" << endl;
cin >> matchPenalty;
cout<<"Enter the value of misMatchPenalty Penalty" << endl;
cin >> misMatchPenalty;
cout<<"Enter the value of gapPenalty Penalty" << endl;
cin >> gapPenalty;
Matrix dp(gene1.length(), gene2.length());
dp.setGenes(gene1, gene2);
dp.setPenalty(misMatchPenalty, gapPenalty,matchPenalty);
dp.setMatrix();
dp.Print_Matrix();
}
How can I implement the above problem in P-threads? So far, I have used two threads to calculate matrix values of 1st column and 1st row simultaneously.But I have no idea how to compute all values of matrix in parallel. Kindly see my source code:
#include<string>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<pthread.h>
using namespace std;
//Global variables --shared by all threads
int matchPenalty;
int misMatchPenalty;
int gapPenalty;
struct gene_struct {
string gene1;
string gene2;
int rowSize;
int colSize;
int **mat;
};
void* set_matrix_row(void *args)
{
struct gene_struct *shared_block = (struct gene_struct *) args;
for (int i = 0; i < shared_block->rowSize; i++)
{
shared_block->mat[i][0] = i * gapPenalty;
}
return NULL;
}
void *set_matrix_column(void *args)
{
struct gene_struct *shared_block = (struct gene_struct *) args;
for (int i = 0; i < shared_block->colSize; i++)
{
shared_block->mat[0][i] = i * gapPenalty;
}
return NULL;
}
void set_Matrix_Diagnol(struct gene_struct shared_block)
{
//How Should I calculate rest of the matrix values using Pthreads?
}
void Print_Matrix(struct gene_struct shared_block)
{
cout<<"\n";
for (int i = 0; i < shared_block.rowSize; i++)
{
for (int j = 0; j < shared_block.colSize; j++)
{
cout << shared_block.mat[i][j] << "\t";
}
cout << "\n";
}
}
int main()
{
pthread_t ptid1, ptid2;
string gene1, gene2;
struct gene_struct shared_block;
cout << "Enter First Gene : ";
cin >> gene1;
cout << "Enter Second Gene : ";
cin >> gene2;
cout<<"Enter the value of Match Penalty" << endl;
cin >> matchPenalty;
cout<<"Enter the value of misMatchPenalty Penalty" << endl;
cin >> misMatchPenalty;
cout<<"Enter the value of gapPenalty Penalty" << endl;
cin >> gapPenalty;
shared_block.gene1 = gene1;
shared_block.gene2 = gene2;
shared_block.rowSize = gene2.length()+1;
shared_block.colSize = gene1.length()+1;
shared_block.mat = new int* [shared_block.rowSize]; //col = gene2+1
for (int i = 0; i < shared_block.rowSize; i++)
{
shared_block.mat[i] = new int[shared_block.colSize];
}
pthread_create(&ptid1, NULL, &set_matrix_row, (void *)&shared_block);
pthread_create(&ptid2, NULL ,&set_matrix_column, (void *)&shared_block);
pthread_join(ptid1,NULL);
pthread_join(ptid2,NULL);
Print_Matrix(shared_block);
}
Related
i have assigment to create c++ program which will multiple 2 uknown size matrix using fork and shared memory, I have write this code but at the end for multiplication result i get all zeros. Sorry for mess code im new in this.
`
`#include<iostream>
#include<math.h>
#include<vector>
#include<signal.h>
#include<unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<sys/wait.h>
using namespace std;
int l, m, n, job_numb;
key_t id_shared_mem;
int **B, **C, **A;
int **generateMatrix(int **matrix, int iterator, int vel){
for (int i = 0; i < iterator; i++)
{
matrix[i] = new int[vel];
for (int j = 0; j < vel; j++)
{
matrix[i][j] = (rand() % 9);
}
}
return matrix;
}
int **generateMatrixC(int **matrix, int iterator, int vel)
{
for (int i = 0; i < iterator; i++)
{
matrix[i] = new int[vel];
}
return matrix;
}
void *writeMatrixResult(int **matrix, int stupac, int red)
{
for (int i = 0; i < stupac; i++)
{
for (int j = 0; j < red; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
return NULL;
}
void write()
{
cout << "Mnozenik = " << endl;
writeMatrixResult(A, l, m);
cout << "Mnozitelj = " << endl;
writeMatrixResult(B, m, l);
cout << "Umnozak = " << endl;
writeMatrixResult(C, l, l);
}
void abort(int sig) {
if (sig == SIGINT) {
for (int i = 0; i < job_numb; i++) wait(NULL);
shmdt(A);
shmdt(B);
shmctl(id_shared_mem, IPC_RMID, NULL);
} else {
write();
shmdt(A);
shmdt(B);
shmctl(id_shared_mem, IPC_RMID, NULL);
}
exit(0);
}
void proces(int procesId)
{
while (job_numb > procesId)
{
int i = 0;
while (i < l)
{
int j = 0;
C[procesId][i] = 0;
while (m > j)
{
C[procesId][i] = C[procesId][i] + A[procesId][j] * B[j][i];
j++;
}
i++;
}
procesId++;
}
}
int main(int argc, char ** argv) {
if (argc != 4) {
cout << " unesite 3 argumenta!" << endl;
return 0;
}
l = atoi(argv[1]);
m = atoi(argv[2]);
n = atoi(argv[3]);
job_numb = l / n;
if (l % n) {
job_numb++;
}
id_shared_mem = shmget(IPC_PRIVATE, sizeof(int) * 10, 0600);
sigset(SIGINT, abort);
A = (int **)shmat(id_shared_mem, NULL, 0);
B = A + l;
C = B + l * m*m;
A = new int *[l];
B = new int *[m];
C = new int *[l];
srand(time(NULL));
A = generateMatrix(A,l, m );
B = generateMatrix(B,m,l);
C = generateMatrixC(C,l,l);
for (int i = 0; i < n; i++)
{
switch (fork()) {
case 0: { //dijete
proces(i);
exit(0);
}
case -1: { //greska
cout << "Fatalna pogreska!" << endl;
exit(1);
}
}
}
for (int i = 0; i < job_numb; i++) wait(NULL);
abort(0);
}`
`
i have try to assign only one value to matrix C like c[1][1] = 2 in proces function to see if it will write any, but still im getting all zeros on printl.
I'm writing a program to find the determinant of a matrix n x n, using Laplace expansion.
Briefly, the program creates a two-dimensional array based on a user request. The users choose the size of the two-dimensional array and fills it in themselves. Next comes the computation of the matrix using Laplace.
The problem is that I can't use the resulting array values in the determinant function. I'm completely new to C ++, so any help would be welcome. The code shown below. Thanks
#include<iostream>
#include<iomanip>
#include<math.h>
using namespace std;
void fin(int**, int, int);
void fout(int**, int, int);
int main() {
int **board, n;
double alpha, beta;
cout << "Enter the number of rows and columns: ";
cin >> n;
cout << endl;
board = new int* [n];
for(int row = 0; row < n; row++)
board[row] = new int[n];
fin(board,n,n);
cout << endl;
fout(board,n,n);
cout << endl;
cout << "Determinant of the matrix is " << determinant(board, n);
cout << endl;
return 0;
}
void fin(int **p, int R, int C)
{
for(int row = 0; row < R; row++)
{
cout << "Enter " << C + 1 << " numbers for row number " << R + 1 << ": ";
for(int col = 0; col < C; col++)
cin >> p[row][col];
cout << endl;
}
}
void fout(int **p, int R, int C)
{
for(int row = 0; row < R; row++)
{
for(int col = 0; col < C; col++)
cout << setw(5) << p[row][col];
cout << endl;
}
}
int determinant( int **result, int n) {
int det = 0;
int submatrix[10][10];
if (n == 2)
return ((result[0][0] * result[1][1]) - (result[1][0] * result[0][1]));
else {
for (int x = 0; x < n; x++) {
int subi = 0;
for (int i = 1; i < n; i++) {
int subj = 0;
for (int j = 0; j < n; j++) {
if (j == x)
continue;
submatrix[subi][subj] = result[i][j];
subj++;
}
subi++;
}
det = det + (pow(-1, x) * result[0][x] * determinant( submatrix, n - 1 ));
}
}
return det;
}
My code works fine when the file Im reading from only contains ints, but when I have floats in the file it doesnt seem to work, for example if I have 1.5 in the file it will only read it as 1 and it wont read any of the numbers after it.
Anyone knows whats causing this? The dynamic array where everything is saved in is a float so Im not sure what to do at this point
#include <iostream>
#include <fstream>
#include <string>
float *allocateArray(std::string fileName, int &arraySize, int &counter)
{
int a = 0;
std::ifstream myReadFile;
myReadFile.open(fileName);
float *arr = new float[arraySize]{0.0};
while (myReadFile >> a)
{
counter++;
if(counter == arraySize)
{
arr[arraySize -1] = a;
}
else
{
float *tempArray = new float[arraySize +1]{0.0};
for(int i = 0; i < arraySize; i++)
{
tempArray[i] = arr[i];
}
delete[] arr;
arraySize++;
arr = new float[arraySize];
for(int x = 0; x < arraySize; x++)
{
arr[x] = tempArray[x];
}
arr[arraySize-1] = a;
}
}
myReadFile.close();
return arr;
}
void output(float *arr, int arraySize,int counter)
{
float sum = 0.0;
for(int x = 0; x < arraySize; x++)
{
sum += arr[x];
}
float average = sum/counter;
std::cout << "Output: ";
for(int i = 0; i < arraySize; i++)
{
if(arr[i] > average)
{
std::cout << arr[i] << " ";
}
}
}
int main()
{
int arraySize = 1;
int counter = 0;
float *arr = allocateArray("input.in", arraySize, counter);
std::cout << "Input: ";
for(int x = 0; x < arraySize; x++)
{
std::cout << arr[x] << " ";
}
output(arr, arraySize, counter);
getchar();
return 0;
}
First i need to re-arrange all the values of my array into ascending order then add it afterwards. For example the user input 9 2 6, it will display in ascending order first ( 2 6 9 ) before it will add the sum 2 8 17.. The problem is my ascending order is not working, is there something wrong in my code?
#include <iostream>
#include<conio.h>
using namespace std;
int numberof_array, value[10], temp;
int i = 0, j;
void input()
{
cout << "Enter number of array:";
cin >> numberof_array;
for (i = 0; i < numberof_array; i++)
{
cout << "Enter value for array [" << i + 1 << "] - ";
cin >> value[i];
cout << endl;
}
}
void computation()
{
// this is where i'll put all the computation
for (j = 0; j < numberof_array; j++)
{
cout << value[j];
}
for (i = 0; i <= numberof_array; i++)
{
for (j = 0; j <= numberof_array - i; j++)
{
if (value[j] > value[j + 1])
{
temp = value[j];
value[j] = value[j + 1];
value[j + 1] = temp;
}
}
}
}
void display()
{
// display all the computation i've got
cout << "\nData after sorting: ";
for (j = 0; j < numberof_array; j++)
{
cout << value[j];
}
getch();
}
int main()
{
input();
computation();
display();
}
void computation(){
for (int j = 0; j < numberof_array; j++) cout << value[j]<<"\t";
for (int i = 0; i <= numberof_array; i++) {
temp = value[i];
int temp_idx = i;
for (int j = i; j < numberof_array; j++) {
if (value[j] < temp) {
temp = value[j];
temp_idx = j;
}
}
int temp_swap = value[i];
value[i] = value[temp_idx];
value[temp_idx] = temp_swap;
}
}
How about changing your second function to something like above.
I have to agree with other commentators that your coding style is not preferred but there might be more to the story than meets the eye.
I have a function "mod_kadane" defined in class "MAX_SUB_MAT" which returns an object.
#define dx 101
class MAX_SUB_MAT
{
public:
int curr_sum, max_sum, left, right, up, down;
MAX_SUB_MAT mod_kadane(int mat[dx][dx], int row, int column)
{
MAX_SUB_MAT objx;
curr_sum = objx.max_sum = INT_MIN;
int sub_mat[row];
for(int L = 0; L < row; L++)
{
memset(sub_mat, 0, sizeof sub_mat);
for(int R = L; R < column; R++)
{
for(int i = 0; i < row; i++)
{
sub_mat[i] += i;//mat[i][R];
}
MAX_SUB_ARR obj;
obj = obj.kadane(sub_mat, row);
curr_sum = obj.maxima;
if(curr_sum > objx.max_sum)
{
objx.max_sum = curr_sum;
objx.left = L;
objx.right = R;
objx.up = obj.left;
objx.down = obj.right;
}
}
}
return objx;
}
};
But when I'm trying to call it from "main":
cin >> row >> column;
int mat[row][column];
for(int i = 0; i < row; i++)
{
for(int j = 0; j < column; j++)
{
cin >> mat[i][j];
}
}
MAX_SUB_MAT objx;
objx = objx.mod_kadane(mat, row, column);
then an error is shown:
error: no matching function for call to 'MAX_SUB_MAT::mod_kadane(int [row][column], int&, int&)'|
But if I remove the 2d array "mat" from both sides then the code works fine.
Here is my full code:
#include<bits/stdc++.h>
#define dx 101
using namespace std;
class MAX_SUB_ARR
{
public:
int max_curr, maxima, left, right;
MAX_SUB_ARR kadane(int arr[], int n)
{
MAX_SUB_ARR obj;
obj.maxima = max_curr = INT_MIN;
//cout << obj.maxima << endl;
/*for(int i = 0; i < n; i++)
cout << arr[i] << endl;*/
for(int i = 0; i < n; i++)
{
if(max_curr < 0)
{
max_curr = arr[i];
obj.left = i;
}
else
{
max_curr += arr[i];
}
//maxima = max(maxima, max_curr);
if(max_curr > obj.maxima)
{
obj.maxima = max_curr;
obj.right = i;
//cout << obj.maxima << endl;
}
}
return obj;
}
};
class MAX_SUB_MAT
{
public:
int curr_sum, max_sum, left, right, up, down;
/* MAX_SUB_MAT(int r, int c)
{
row = r;
column = c;
}*/
MAX_SUB_MAT mod_kadane(int mat[dx][dx], int row, int column)
{
MAX_SUB_MAT objx;
curr_sum = objx.max_sum = INT_MIN;
int sub_mat[row];
for(int L = 0; L < row; L++)
{
memset(sub_mat, 0, sizeof sub_mat);
for(int R = L; R < column; R++)
{
for(int i = 0; i < row; i++)
{
sub_mat[i] += i;//mat[i][R];
}
MAX_SUB_ARR obj;
obj = obj.kadane(sub_mat, row);
curr_sum = obj.maxima;
if(curr_sum > objx.max_sum)
{
objx.max_sum = curr_sum;
objx.left = L;
objx.right = R;
objx.up = obj.left;
objx.down = obj.right;
}
}
}
return objx;
}
};
int main()
{
int row, column;
printf("Number of rows you want to insert?:\n");
cin >> row;
printf("Number of columns you want to insert?:\n");
cin >> column;
int mat[row][column];
if(row && column)
{
for(int i = 0; i < row; i++)
{
for(int j = 0; j < column; j++)
{
cin >> mat[i][j];
}
}
//int curr_sum, max_sum, left, right, up, down;
//MAX_SUB_MAT objx = new MAX_SUB_MAT(row, column);
MAX_SUB_MAT objx;
objx = objx.mod_kadane(mat, row, column);
for(int i = objx.up; i <= objx.down; i++)
{
for(int j = objx.left; j <= objx.right; j++)
{
cout << mat[i][j] << " ";
}
cout << endl;
}
}
return 0;
}
It is not true that in C or C++ we cannot declare a function with two dimensional array parameter with both sizes specified.
See: http://c-faq.com/aryptr/pass2dary.html
The problem has been correctly explained by #AlanStokes in his comments!