Beginner here...
Doing a code to check language performance in Cpp, Java and Python.
The code must generate a random number N (1-60), fill a NxN matrix with random numbers between 0 and 9 and calculate its determinant.
I started with cpp, but sometimes it succeeds, sometimes it fails. My guess is that crashes are related to bigger than "long long int" numbers. Can you guys please check my code?
GNU GCC / CodeBlocks.
Thanks,
Guile.
#include <iostream>
#include <time.h>
using namespace std;
struct Mat{
int N = 2;
int mat[60][60];
long long int det;
};
void setSize(Mat *Size){
srand (time(NULL));
do {
Size->N = rand()%60;
}
while (Size->N < 1);
}
void setMatrix (Mat *mat){
srand (time(NULL));
for (int i = 0; i < mat->N; i++){
for (int j = 0; j < mat->N; j++){
mat->mat[i][j] = rand()%10;
}
}
}
void det(Mat *m1){
int i, j, k;
long long int Ratio;
long long int determinant;
for(i = 0; i < m1->N; i++){
for(j = 0; j < m1->N; j++){
if(j>i){
Ratio = m1->mat[j][i]/m1->mat[i][i];
for(k = 0; k < m1->N; k++){
m1->mat[j][k] -= Ratio * m1->mat[i][k];
}
}
}
}
determinant = 1;
for(i = 0; i < m1->N; i++)
determinant *= m1->mat[i][i];
m1->det = determinant;
}
int main (void){
Mat M1;
setSize(&M1);
setMatrix (&M1);
det(&M1);
cout<<"Matrix size: "<<M1.N<<endl;
cout<<"Matrix determinant: "<<M1.det<<"\n\n";
return 0;
}
Inside your function setMatrix:
for (int j = 0; j < mat->N; j++){
mat->mat[i][j] = rand()%10;
}
rand() % 10 can sometimes generate 0 as well, thus putting zeroes inside your matrix. This will cause a floating-point exception when you do:
Ratio = m1->mat[j][i]/m1->mat[i][i];
This line will again cause an issue when you do
m1->mat[j][k] -= Ratio * m1->mat[i][k];
which can again set a zero in your matrix at mat[j][k] later which can become the denominator again, causing the floating-point exception.
Related
I'm trying to eliminate some number from range (170-2500) and then calculate the remaining numbers after the elimination. The numbers composed of 3 digits from number's list (2,5,6,7). I have tried using Cartesian Product to generate the numbers, but I confused how to eliminate the numbers from the range. The cartesian product code is obtained from geeksforgeeks. I know how to calculate the remaining numbers but I confused with the numbers that will be eliminated.
void findCart(int arr1[], int n)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
printf("{%d%d%d}, ", arr1[i], arr1[j], arr1[k]);
}
int main()
{
min=170;
max=2500;
int arr1[] = {2,5,6,7};
int n1 = sizeof(arr1) / sizeof(arr1[0]);
findCart(arr1, n1, number);
int count=0;
if (number>=min && number<=max){
count++;
}
int total=max-min+1;
int result=total-count;
cout<<result;
return 0;
}
Not sure that I understand your question, but from your code, i think you are trying to do this: create an integer number from list of digits then check if it is from min to max, then print number of remaining in range.
try this code, hope you understand my idea:
// return total number which are meet conditions
int findCart(int arr1[], int n, int min, int max)
{
int totalNumbers = 0;
int number = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++){
number = arr1[i]*100 + arr1[j]*10 + arr1[k];
if ( number >= min && number <= max )
++totalNumbers;
}
return totalNumbers;
}
int main()
{
int min=170;
int max=2500;
int arr1[] = {2,5,6,7};
int n1 = sizeof(arr1) / sizeof(arr1[0]);
int totalNumberFound = findCart(arr1, n1, min, max);
int total=max-min+1;
int result=total- totalNumberFound;
cout<<result;
return 0;
}
I put in my program two loops - one fills 2D array with one value N0, and next loop is generating random number. And my program does not work when I have loop for array. I get "Unhandled exception... (parameters: 0x00000003)". But without first loop it works correctly. Thanks for help.
#include <iostream>
#include <vector>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
using namespace std;
const double czas = 1E9;
int main()
{
//Declaration of variables
const int k = 20;
const int L = 30;
double N0 = 7.9E9;
int t,i,j, WalkerAmount;
double excitation, ExcitationAmount;
double slab[30][600];
//Random number generator
boost::random::mt19937 gen;
boost::random::uniform_int_distribution<> numberGenerator(1, 4);
//Filling slab with excitation
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++) { slab[i][j] = N0; }
}
//Time loop
for (t = 0; t < czas; t++) {
WalkerAmount = 0;
ExcitationAmount = 0;
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++)
{
int r = numberGenerator(gen);
cout << r << endl;
}
}
}
system("pause");
return 0;
}
Arrays in C++ are indexed from 0 to n-1 where n is the capacity of the array. Then, the code following code is wrong.
int main()
{
//Declaration of variables
const int k = 20;
const int L = 30;
double N0 = 7.9E9;
double slab[30][600];
// [...]
for (int i = 0; i <= L; i++)
{
for (int j = 0; j <= k*L; j++) { slab[i][j] = N0; }
}
}
When you initialize your array, you always go one steep too far. As you consider the case where i == L and j == k*L you reach an area in the memory that out of your array.
The loop you want to execute is
for (int i = 0; i < L; i++)
for (int j = 0; j < k*L; j++)
// Initialize
I have about 1000 lines of code that I wrote in C for a linear programming solver (interior point algorithm). I realized that I need to use Eigen to calculate a matrix inverse, so now I am running my code in C++ instead (runs just fine, it seems). Now I have a bunch of arrays declared in C format, for example: A[30][30];
In my program, I do a bunch of matrix calculations and then need to find an inverse of a matrix at some point, let's call it matrix L[30][30]. To use Eigen, I need to have it in a special Eigen matrix format to call the function m.inverse like this:
//cout << "The inverse of L is:\n" << L.inverse() << endl;
My goal is to find a way... ANY way, to get my data from L to a format that Eigen will accept so I can run this thing. I've spent the last 2 hours researching this and have come up with nothing. :-( I'm fairly new to C, so please be as thorough as you can. I want the most simple method possible. I've read about mappings, but I'm not very clear on pointers sadly (which seems to be an integral part). Is there a way to just loop through each row and column and copy them into an Eigen matrix?
While I'm asking, will I need to take the resultant Eigen matrix and turn it back into a C array? How would that process work? Thanks in advance for any help! I've spent about 50-60 hours on this and it's due this week! This is the LAST thing I need to do and I'll be done with my term project. It's a math class, so the programming side of things are a little fuzzy for me but I'm learning a lot.
Possibly relevant information:
-Running on Windows 10 i7 processor Sony VAIO
-Compiling with CodeBlocks in C++, but originally written in C
-This code is all in a while loop that may be iterated through 10 times or so.
-The matrix inverse needs to be calculated for this matrix L each iteration, and the data will be different each time.
Please help! I'm willing to learn, but I need guidance and this class is online so I have virtually none. Thanks so much in advance!
Edit - I saw this and tried to implement it to no avail, but it seems like the solution if I can figure this out:
"Suppose you have an array with double values of size nRows x nCols.
double *X; // non-NULL pointer to some data
You can create an nRows x nCols size double matrix using the Map functionality like this:
MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );
The Map operation maps the existing memory region into the Eigen’s data structures. A single line like this allows to avoid to write ugly code of matrix creation, for loop with copying each element in good order etc."
This seems to be a nice solution, but I am clueless on how to do anything with that "double *X" that says to "point to some data". I began looking up pointers and such and it didn't help clarify - I saw all kinds of things about pointing to multi-dimensional arrays that didn't seem to help.
I also don't quite understand the format of the second line. Is every capital X there just going to be the same as the matrix *X in the line before? What would I need to declare/create for that? Or is there an easier way that all of this?
EDIT2: Here is what I have in my program, essentially - this is significantly shrunken down, sorry if it's still too long.
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
typedef Matrix<double, 30, 30> Matrix30d;
double L[30][30] ={{0}};
double Ax[30][30] = {{0}}; //[A] times [x]
double At[30][30] = {{0}}; //A transpose
double ct[30][30] = {{0}}; //c transpose
double x[30][30] = {{0}}; //primal solution
double w[30][30] = {{0}}; //omega, dual solution
double s[30][30] = {{0}}; //dual slack
double u[30][30] = {{0}}; //[c]t - [A]t x [w] - [s]
double Atxw[30][30] = {{0}}; //A transpose times omega
double t[30][30] = {{0}}; //RHS - [A]x[x]
double v[30][30] = {{0}}; //mu - xij * sij
double p[30][30] = {{0}}; //vij / xij
double D2[30][30] = {{0}}; //diagonal of xij/sij
double AD2[30][30] = {{0}}; //[A] x [D2]
double AD2xAt[30][30] = {{0}}; //[AD2] x [At]
double uminp[30][30] = {{0}}; //[u] - [p]
double AD2xuminp[30][30] = {{0}}; //[AD2] x [uminp]
double z[30][30] = {{0}}; //[AD2] x [uminp] + [t]
double Atxdw[30][30] = {{0}}; //[At] x [dw]
double xt[30][30] = {{0}}; //x transpose
double bt[30][30] = {{0}}; //b transpose
Matrix30d Inv; //C++ style matrix for Eigen, maybe needed?
int main(){
int r1; //rows of A
int c1; //columns of A
int i; //row and column counters
int j;
int k;
double sum = 0;
double size; //size of square matrix being inverted [L]
double *pointer[30][30];
FILE *myLPproblem;
myLPproblem = fopen("LPproblem.txt", "r"); //Opens file and reads in data
float firstLine[4];
int Anz;
for (i = 0; i < 4; i++)
{
fscanf(myLPproblem, "%f", &firstLine[i]);
}
r1 = firstLine[0];
c1 = firstLine[1];
Anz = firstLine[2];
double A[r1][c1];
double b[r1][1];
double c[1][c1];
int Ap[c1+1];
int Ai[Anz];
double Ax2[Anz];
for(i=0; i<r1; i++){
for(j=0; j<c1; j++){
A[i][j]=0;
}
}
for (i = 0; i < (c1 + 1); i++)
{
fscanf(myLPproblem, "%d", &Ap[i]);
}
for (i = 0; i < (Anz); i++)
{
fscanf(myLPproblem, "%d", &Ai[i]);
}
for (i = 0; i < (Anz); i++)
{
fscanf(myLPproblem, "%lf", &Ax2[i]);
}
for (i = 0; i < (r1); i++)
{
fscanf(myLPproblem, "%lf", &b[i][0]);
}
for (i = 0; i < (c1); i++)
{
fscanf(myLPproblem, "%lf", &c[0][i]);
}
fclose(myLPproblem);
int row;
double xval;
int Apj;
int Apj2;
for(j=0; j<c1; j++){
Apj = Ap[j];
Apj2 = Ap[j+1];
for(i=Apj; i<Apj2; i++){
row = Ai[i];
xval = Ax2[i];
A[row][j] = xval;
}
}
size = r1;
for(i=0; i<c1; i++) //Create c transpose
{
ct[i][0] = c[0][i];
}
for(i=0; i<r1; i++) //Create b transpose
{
bt[i][0] = b[0][i];
}
for(i=0; i<c1; i++) //Create A transpose
{
for(j=0; j<r1; j++)
{
At[i][j] = A[j][i];
}
}
while(1){ //Main loop for iterations
for (i = 0; i <= r1; i++) { //Multiply [A] times [x]
for (j = 0; j <= 1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + A[i][k] * x[k][j];
}
Ax[i][j] = sum;
}
}
sum = 0; //Multiply [At] times [w]
for (i = 0; i <= c1; i++){
for (j = 0; j <= 1; j++) {
sum = 0;
for (k = 0; k <= r1; k++) {
sum = sum + At[i][k] * w[k][j];
}
Atxw[i][j] = sum;
}
}
for(i=0; i<c1; i++) //Subtraction to create matrix u
{for(j=0; j<1; j++)
{
u[i][j] = (ct[i][j]) - (Atxw[i][j]) - (s[i][j]);
}
}
for(i=0; i<r1; i++) //Subtraction to create matrix t
{for(j=0; j<1; j++)
{
t[i][j] = (b[i][j]) - (Ax[i][j]);
}
}
for(i=0; i<c1; i++) //Subtract and multiply to make matrix v
{for(j=0; j<1; j++)
{
v[i][j] = mu - x[i][j]*s[i][j];
}
}
for(i=0; i<c1; i++) //create matrix p
{for(j=0; j<1; j++)
{
p[i][j] = v[i][j] / x[i][j];
}
}
for(i=0; i<c1; i++) //create matrix D2
{for(j=0; j<c1; j++)
{
if(i == j){
D2[i][j] = x[i][0] / s[i][0];
}else{
D2[i][j] = 0;
}
}
}
sum = 0;
for (i = 0; i <= r1; i++) { //Multiply [A] times [D2]
for (j = 0; j <= c1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + A[i][k] * D2[k][j];
}
AD2[i][j] = sum;
}
}
sum = 0;
for (i = 0; i <= r1; i++) { //Multiply [AD2] times [At], to be inverted!
for (j = 0; j <= r1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + AD2[i][k] * At[k][j];
}
AD2xAt[i][j] = sum;
}
}
//Here is where I need to calculate the inverse (and determinant probably) of matrix AD2xAt. I'd like to inverse to then be stored as [L].
//cout << "The determinant of AD2xAt is " << AD2xAt.determinant() << endl;
//cout << "The inverse of AD2xAt is:\n" << AD2xAt.inverse() << endl;
printf("\n\nThe inverse of AD2xAt, L, is : \n\n"); //print matrix L
for (i=0; i<size; i++)
{
for (j=0; j<size; j++)
{
printf("%.3f\t",AD2xAt[i][j]);
}
printf("\n");
}
}
return 0;
}
In a nutshell, it reads matrices from a file, calculates a bunch of matrices, then needs to invert AD2xAt and store it as L. The critical part is at the end, where I need to take the inverse (scroll to the bottom - I have it commented).
Have you tried
Map<MatrixXd>(A[0],30,30).inverse() ??
– ggael
What you're proposing seems like it would be doing both at once or
something?
Right, the Map<MatrixXd>() returns the Eigen's MatrixXd, on which the method inverse() is called.
May I ask what the [0] is after A?
[0] is the array subscript operator [] designating the 0-th element; A[0] is the initial row of the matrix A[30][30] and is converted to the pointer to A[0][0] corresponding to the X you saw.
I have this program that is trying to determine how many unique items are within some intersecting sets. The amount of input entirely depends on the the first value n, and then the amount of sets entered afterward. For example, if I start with entering n = 2, I am expected to enter 2 integers. The program then determines how many intersections there are between n items (this is like choosing 2 items from n items). This goes on as k increments. But that's kind of beyond the point. Just some background info.
My program adapts correctly and accepts the proper amount of input, but it stops working properly before the first for loop that is outside of the while loop. What I have tried to do is make a vector of integer vectors and then add every other row (when index starts at 0 AND index starts at 1). But I am guessing I have constructed my vectors incorrectly. Does anybody see an error in my vector logic?
#include <iostream>
#include <vector>
using namespace std;
int fact (int m) {
if (m <= 1)
return 1;
return m * fact(m - 1);
}
int comb (int n, int k) {
return fact(n)/(fact(n-k)*fact(k));
}
int main() {
int n = 0;
int k = 2;
int sum = 0;
int diff = 0;
int final = 0;
vector <vector <int> > arr;
cin >> n;
while (n > 0) {
vector <int> row;
int u;
for (int i = 0; i < n ; ++i) {
cin >> u;
row.push_back(u);
}
arr.push_back(row);
n = comb(row.size(), k);
k++;
}
for (int i = 0; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
sum += arr[i][j];
for (int i = 1; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
diff += arr[i][j];
final = sum - diff;
cout << final;
return 0;
}
for (int i = 0; i < arr.size(); i+=2)
^
You want to do i+=2 or i=i+2, else the value of i is never changed, leading to an infinite loop.
I have no idea what's wrong with my code ... It always return zeros in all the elements. A hint of where is the problem would be great :)
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include <windows.h>
using namespace std;
int nGlobalCount = 0;
int thread_index = 0;
int num_of_thr=5;
int a[4][4], b[4][4], c[4][4];
int i, j, k;
struct v {
int i; /*row*/
int j; /*column*/
};
DWORD ThreadProc (LPVOID lpdwThreadParam ) {
//
struct v *input = (struct v *)lpdwThreadParam;
int avg=4*4/num_of_thr;
int count=0;
for(int i = 0; i <= 3 ; i++) {
for(int j = 0; j <= 3; j++) {
int sum=0;
for ( k = 0 ; k <= 3; k++) {
sum=sum+((a[input->i][k])*(b[k][input->j]));
c[input->i][input->j]=sum;
count++;
}
}
}
//Print Thread Number
//printf ("Thread #: %d\n", *((int*)lpdwThreadParam));
//Reduce the count
return 0;
}
int main() {
// int x=0;
cout<<"enter no of threads : ";
cin>>num_of_thr;
DWORD ThreadIds[num_of_thr];
HANDLE ThreadHandles[num_of_thr];
//struct v {
// int i; /*row*/
// int j; /*column*/
//};
struct v data[num_of_thr];
int i , j , k;
for ( int i = 0 ; i <= 3; i++) {
for (int j = 0 ; j <= 3 ; j++) {
a[i][j] = rand() % 10;
b[i][j] = rand() % 10;
c[i][j] = 0;
}
}
for(int i = 0; i < num_of_thr/2; i++) {
for(int j = 0; j < num_of_thr/2; j++) {
data[thread_index].i = i;
data[thread_index].j = j;
ThreadHandles[thread_index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, &data[thread_index], 0,&ThreadIds[thread_index]);
thread_index++;
}
}
WaitForMultipleObjects(num_of_thr, ThreadHandles, TRUE, INFINITE);
cout<<"The resultant matrix is "<<endl;
for ( i = 0 ; i < 4; i++) {
for ( j = 0 ; j < 4 ; j++)
cout<<c[i][j]<<" ";
cout<<endl;
}
for (int i=0; i<num_of_thr; i++)
CloseHandle(ThreadHandles[i]);
return 0;
}
At a GLANCE, your sum declaration in the loop looks sketchy.
for(int i = 0; i <= 3 ; i++) {
for(int j = 0; j <= 3; j++) {
for ( k = 0 ; k <= 3; k++)
{
int sum=sum+((a[input->i][k])*(b[k][input->j])); // this declaration seems wrong
c[input->i][input->j]=sum;
count++;
}
}
}
Each inner loop you redeclare sum, effectively making it 0. You might want to move the declaration up one or two loops from the assignment depending on what you are trying to achieve.
Do you realise that you have two separate sets of variables named a, b and c? One is local to the function main, and the other is a static for the whole program. I suspect that this is not what you intended. Try deleting the one that is local to main.
Martyn
A few things I found while poking about in addition to the other issues noted previously:
What are you compiling this with? With VC++ 2010 it "works", as in it outputs non-zeroes, although it complains about the DWORD ThreadIds[num_of_thr]; array declaration with a non-constant array size (I just made num_of_thr a constant and commented out the cin to test it quickly).
Are you sure you are inputting a valid number of threads with cin >> num_of_thr; For example, if num_of_thr was 0 this would explain the zeroes output. A simple cout here for num_of_thr would be useful.
In your data initialization loop starting with for(int i = 0; i < num_of_thr/2; i++) { you are not correctly counting threads which will result in an array underflow or overflow. For example, if num_of_thr is 5 then num_of_thr/2 is 2 which results in initializing only the elements 0..3 leaving the last element uninitialized. An array underflow is technically ok although the later CloseHandle() call will fail when it tries to free an essentially random handle. If you enter a larger number of threads you will overflow all your arrays (try it with num_of_thr=10 for example).
If it still doesn't work try removing the threading to see if the threading or code itself is the source of the problem. For example, you can call the ThreadProc() function manually in a loop instead of from within threads. Either trace through the program with a debugger or output logs to stdout/file (which would also work in the threading model).
Instead of a random source matrix I would use a few fixed values at first with a known result. This will make it easier to determine if the code is actually computing the correct result.