TL;DR - Have some instructions on how to use some C++ code from a github readme (see below) and I'm struggling to implement them as I have never done any C++ before.
So first things first; I am a science student with an okay background in python. I need to use some code thats been written in C++ (I have never used C++ before). Over the past few days I've been googling like a madman in order to figure out how to use the code. Nonetheless excuse me if I've made silly pythonic mistakes everywhere. The github gives these instructions:
"To generate an adjacency matrix for a single statistically homogeneous network in a C++ program, include the header file secorder_rec_1p.hpp and call secorder_rec_1p as
gsl_matrix *W = secorder_rec_1p(N_nodes, p, alpha_recip, alpha_conv,alpha_div, cc_chain, rng);
where N_nodes is the number of nodes in the network and rng is a pointer to an initialized gsl random number generator. W is an adjacency matrix where W_ij=1 if there is a connection from node j onto node i and is zero otherwise."
For someone who has never done C++ before this was at first rather confusing. After much googling etc it is now less confusing and I have a .c file that I was hoping would do the trick. Unfortunately it's giving me an error I somewhat understand but dont know how to fix.
so my code is:
#include "secorder_rec_1p.hpp"
#include <time.h>
#include <gsl/gsl_rng.h>
using namespace std;
extern int N;
extern double p, recip, conv, divg, chain;
int main (){
int N;
N = 1000;
gsl_rng * rng = gsl_rng_alloc(gsl_rng_taus); //I'm not really sure what it does but I don't get any mention of this in the errors so I think it's ok. Not entirely sure if this is a "pointer to an initialized gsl random num generator"
double p, recip, conv, divg, chain;
recip = 0.1;
p = 0.1;
conv = 0.1;
divg = 0.1;
chain = 0.1;
int W [N][N];
int i,j;
double result = rand()/ RAND_MAX;
for(i=0; i<N; i++)
for(j=0; j<N; j++)
{
if(result > p){
W [i][j] = 1;
} else {
W[i][j] = 0;
}
}
gsl_matrix *W = secorder_rec_1p(N, p, recip, conv, divg, chain, rng);
}
I'm getting a declaration error when I try to "make" the .c file (this is compiling it right? I need to do this before I can actually run the script?). The error cites a conflicting declaration with my W's.
My (obviously incorrect) understanding is that I'm creating an N by N array (matrix?) that is filled with 1s and 0s where element M_ij is 1 with a probability p and 0 otherwise.
Then this is where my understanding falls apart a little, but *W means it points to the thing labelled by W, so it should be my matrix and a gsl_matrix that are equal to the output of that function. I'm not sure what the equals means in this case because it should be generating a new matrix. So if this was python I'd expect the name of my new matrix to be on the left hand side of the equals and the stuff on the right the code used to generate it. I'm not sure what's going on here though.
Any help with my error as well as information about how c++ works etc is greatly appreciated.
Related
I am very new to C++ and I am trying to deconstruct someone's code, and I am not quite sure what to Google for, hence I am just going to ask here. This is a second attempt at a question I asked earlier which was poorly posed. Should this one not measure up, please let me know and I shall try to rectify.
Here is a structurally identical MWE, of the piece of code I am trying to understand.
#include <iostream>
using namespace std;
int square(int x){
// Function that squares without using *
int result = 0;
for (int counter = 0; counter < x; ++counter){
result += x;
}
return result;
}
int main()
{
int const D = 4;
int myArray[D] = {}; // all elements 0 in C++
char colour[D] = {'c','o','e','g'}; // Initialize String Array
int AEST = 5; // Initialise AEST
for (int d =0; d<D; d++){
if (colour[d]!='c' && colour[d]!='o'){
double aux= square (d);
if (aux!=0){
myArray[d]=aux;
}else{
return AEST;
}
}
}
// Lets see what we achieved.
for (int d =0; d<D; d++){
cout << myArray[d];
}
return 0;
}
Now then, lets crack on with some questions.
Precisely what I do not fully understand is this block:
}else{
return AEST;
}
Please not, AEST is not an error code, it is a numerical value that the code calculates. I have only initialized it here for the purpose of this MWE, but in actuality, it is calculated earlier on in the original code block.
My question is as follows:
The if statement is only true if the colours are not c or o and in which case we square d. In the MWE we square d twice. Hence, is the code then saying that we break out of the loop (with return AEST) IF we stumble upon a colour that is not c or o? But if we do break out of the loop under these conditions, why must we return AEST? It is already initialised AEST=5 earlier on, and nothing we do inside this loop will affect it (remember this block is structurally identical to what I am trying to understand, but obviously not fully identical). This is why I do not understand the else bit.
Again, if there is not enough information, please let me know.
The return AEST part in question exits the main() function. That means the program exits in state 5.
This is done to have some sort of error code detection. For example. If you have various things that can go wrong, you try to retun those with specific codes so you can look up and identify where the problem occured.
It is common to return 0 if everything is fine.
I'm still a newbie to C++ and I've been trying to modularize some spaghetti code that was given to me. So far (apart from learning how to use git and installing the rarray library to replace the automatic arrays with them) I've been sort of stumped as to how to modularize things and then compile it via make.
I understand that I must create prototypes in a header, create my object files from my functions, and then compile it all with a 'driver' code. Running/writing a make file is not my concern, but it's how to begin modularizing code like this; I'm not sure how to make functions that modify arrays!
Any pointers in the right direction would be amazing. I can clarify more if necessary.
#include <cmath>
#include <iostream>
#include <rarray> // Including the rarray library.
#include <rarrayio> // rarray input/output, if necessary. Probably not.
int main()
{
// ants walk on a table
rarray<float,2> number_of_ants(356,356);
rarray<float,2> new_number_of_ants(356,356);
rarray<float,2> velocity_of_ants(356,356);
const int total_ants = 1010; // initial number of ants
// initialize
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
velocity_of_ants[i][j] = M_PI*(sin((2*M_PI*(i+j))/3560)+1);
}
}
int n = 0;
float z = 0;
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
number_of_ants[i][j] = 0.0;
}
}
while (n < total_ants) {
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
z += sin(0.3*(i+j));
if (z>1 and n!=total_ants) {
number_of_ants[i][j] += 1;
n += 1;
}
}
}
}
// run simulation
for (int t = 0; t < 40; t++) {
float totants = 0.0;
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
totants += number_of_ants[i][j];
}
}
std::cout << t<< " " << totants << std::endl;
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
new_number_of_ants[i][j] = 0.0;
}
}
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
int di = 1.9*sin(velocity_of_ants[i][j]);
int dj = 1.9*cos(velocity_of_ants[i][j]);
int i2 = i + di;
int j2 = j + dj;
// some ants do not walk
new_number_of_ants[i][j]+=0.8*number_of_ants[i][j];
// the rest of the ants walk, but some fall of the table
if (i2>0 and i2>=356 and j2<0 and j2>=356) {
new_number_of_ants[i2][j2]+=0.2*number_of_ants[i][j];
}
}
}
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
number_of_ants[i][j] = new_number_of_ants[i][j];
totants += number_of_ants[i][j];
}
}
}
return 0;
}
I've been sort of stumped as to how to modularize things and then compile it via make.
That might be in part due to the code you are trying to modularize. Modularization is an idiom that is often used to help separate problem domains so that if one area of code has an issue, it won't necessarily* affect another area, and is especially useful when building larger applications; modularization is also one of the key points to classes in object oriented design.
*necessarily with regards to "spaghettification", that is, if the code really is "spaghetti code", often modifying or fixing one area of code most certainly affects other areas of code with unintended or unforeseen consequences, in other words, not modular.
The code you've posted is 63 lines (the main function), and doesn't really require any modularization. Though if you wanted to, you'd want to look at what could be modularized and what should be, but again, there isn't really much in the way to separate out, aside from making separate functions (which would just add to the code bulk). And since you asked specifically
I'm not sure how to make functions that modify arrays!
That can be done with the following:
// to pass a variable by reference (so as to avoid making copies), just give the type with the & symbol
void run_simulation(rarray<float,2>& noa, rarray<float,2>& new_noa, rarray<float,2>& voa)
{
// do something with the arrays
}
int main()
{
// ants walk on a table
rarray<float,2> number_of_ants(356,356);
rarray<float,2> new_number_of_ants(356,356);
rarray<float,2> velocity_of_ants(356,356);
...
run_simulation(number_of_ants, new_number_of_ants, velocity_of_ants);
...
}
Also, it should be noted there's a potential bug in your code; under the run simulation loop, you declare float totants = 0.0; then act on that variable until the end of the loop, at which point you still modify it with totants += number_of_ants[i][j];. If this variable is to be used to keep a 'running' total without being reset, you'd need to move the totants declaration outside of the for loop, otherwise, strictly speaking, that last totants += statement is not necessary.
Hope that can help add some clarity.
Except for replacing the magic numbers with constants in the beginning, there is not much that can be done to improve scientific code as barely anything is reusable.
The only part that is repeated is:
for (int i=0;i<356;i++) {
for (int j=0;j<356;j++) {
new_number_of_ants[i][j] = 0.0;
}
}
Which you can extract as a function (I have not replaced the magic numbers, you should do that first and give them as parameters):
void zeroRarray(rarray<float, 2> number_of_ants) {
for (int i = 0; i < 356; i++) {
for (int j = 0; j < 356; j++) {
number_of_ants[i][j] = 0.0;
}
}
}
And call like:
zeroRarray(number_of_ants); // Btw the name of this rarray is misleading!
Also, replace the mathematical expressions with function calls:
velocity_of_ants[i][j] = M_PI* (sin((2 * M_PI * (i + j)) / 3560) + 1);
with:
velocity_of_ants[i][j] = calculateSomething(i, j);
where the function looks something like:
double calculateSomethingHere(int i, int j) {
return M_PI * (sin((2 * M_PI * (i + j)) / 3560) + 1);
}
so you can give these long and insightful names and focus on what each part of your code does and not what it looks like.
Most IDE's have a refactoring functionality built-in where you highlight part of code that you want to extract and right-click and select Extract function from Refactor (or something similar).
If your code is short (e.g under 200 lines) there is not much you can do except extracting parts of your code that are very abstract. The next step is to write a class for ants and what ever these ants are doing, but there is little benefit for this unless you have more code.
This is not spaghetti code at all. The control structure is actually quite straight-forward (a series of loops, sometimes nested). From the manner csome constructs are being used, it has been translated from some other programming language to C++ without much effort to turn it from the original language to "effective C++" (i.e. it is C++ written with techniques from another language). But my guess is that the original language was somewhat different from C++ - or that the original code did not make a lot of use of that language's features.
If you want to modularise it, consider breaking some things into separately, appropriately named, functions.
Get rid of the magic values (like 356, 3560, 0.3, 40, 1.9, etc). Turn them into named constants (if they are to be fixed at compile time) or named variables (if there is a reasonable chance you may wish them to be inputs to the code at some time in the future). Bear in mind that M_PI is not actually standard in C or C++ (it is common to a number of C and C++ implementations, but is not standard so is not guaranteed to work with all compilers).
Work out what rarray is, and work out how to replace it with a standard C++ container. My guess, from the usage, is that rarray<float, 2> number_if_ants(356,356) represents a two-dimensional array of floats, with both dimensions equal to 356. As such, it might be appropriate to use a std::vector<std::vector<float> > (any version of C++) or (in C++11) std::array<std::array<float, dimension>, dimension> (where dimension is my arbitrary name to replace your magic value of 356). That may look a bit more complicated, but can be made much simpler with the help of a couple of tyepdefs. In the long run, C++ developers will understand the code better than they will if you insist on using rarray.
Look carefully at operations that work on the C++ standard containers. For example, construction and resizing of a std::vector - by default - initialises elements to zero in many circumstances. You might be able replace some of sets of nested loops with a single statement.
Also, dig into the standard algorithms (in header algorithm). They can act on a range of elements in any std::vector - via iterators - and possibly do other things directly that this code needs nested loops for.
I have the following code compiled in linux terminal (c++ in linux) and am using OpenCv 2.4.3.
However, am getting a segmentation fault in run time and I really have no clue as to why. I have placed differnt cout statements to know if the program processed to the particular stage but in vain. Could you please help me? Please explain me what exactly is this segmentation fault. Am stuck here for a long time.
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main()
{
cout<<"check"<<flush;
Mat src,src_gray,dst;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
char* window_name = "sharpness estimate";
int freq,rows,cols =0;
double *estimate,*min = 0;
Point *minLoc,*maxLoc = 0;
src = imread("/home/siddarth/examplescv/erez images/image53.jpg");
if( !src.data )
{
return -1;
}
namedWindow(window_name,CV_WINDOW_AUTOSIZE);
Mat abs_dst;
cvtColor(src,src_gray,CV_RGB2GRAY);
Laplacian(src_gray,dst,ddepth,kernel_size,scale,delta,BORDER_DEFAULT);
convertScaleAbs(dst, abs_dst);
minMaxLoc(dst,min,estimate,minLoc,maxLoc,noArray());
Size s = dst.size();
rows = s.height;
cols = s.width;
cout<<rows<<endl<<cols<<endl;
for(int i=0;i<=rows;i++)
{
for(int j=0;j<=cols;j++)
{
if(dst.at<double>(i,j) >= *estimate-100
&& dst.at<double>(i,j) <= *estimate+100)
{
cout<<freq++;
}
}
}
cout<<"estimate :"<<*estimate<<endl;
cout<<"frequency :"<<freq<<endl;
imshow(window_name,abs_dst);
waitKey(1000);
return 0;
}
The code doesn't cross the first "check" print statement just after the main function declaration. That is the confusing issue. But once I flushed the first print statement, it got executed. I am still facing issues.
Make sure you insert std::endl into cout so that the buffer is flushed. This will probably be why you're not seeing any output.
One immediate issue is that your for loops check the condition with <=, meaning that you're probably going one past the end. But since you're using at, you should have an exception thrown (assuming this Mat type acts like a standard container).
Also, you're creating lots of pointers to pass as some function arguments (for example, double* estimate). This doesn't actually give you a double object though, just a pointer. Unless the function you're passing them to is allocating a double for you (which I hope it's not), you're doing it wrong. You should be doing:
double estimate;
minMaxLoc(/* ... */, &estimate, /* ... */);
You'll need to do that with all of the values you're getting through output parameters.
Another thing to note: Doing int i, j = 0; only initialises j to 0, but not i. You need to do int i = 0, j = 0;.
Okay, I'm going to explain why fixing the initialisers works. I had to look up the definition of minMaxLoc to see what happens. Basically, the function is something like the following:
void setToFive(int* x)
{
if (x) {
*x = 5;
}
}
This function will take a pointer to an int, and then set that int to the value 5. However, if the pointer passed is a null pointer, the value will not be set (otherwise there'll be undefined behaviour because you're derefencing a null pointer). Basically, passing a null pointer says "I don't care about this value so don't give it to me".
Now when you were initialising your pointers, you were doing:
double *estimate, *min = 0;
This only sets min to the null pointer. Since estimate is left uninitialized, you can't rely on its value being null. You need to provide an initialiser for each declarator:
double *estimate = 0, *min = 0;
Thanks to #sftrabbit. The problem was the initialization. instead of
int freq,rows,cols=0;
The change was
int freq=0,rows=0,cols=0;
this removed the segmentation fault. Thanks a lot for your help :).
Since you are in a Linux environment, you can use valgrind to find out exactly where the segmentation fault is happening. Just type valgrind before the name of the program, or the way you execute your program. For example, if you execute your program with the following command:
hello -print
issue the following command instead:
valgrind hello -print
I see you already solved this one, but this may be helpful in the future!
as the title explains this is a program to find lcm of numbers between 1 to 20. i found an algorithm to do this, here's the link
http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml
there is a java applet on the webpage that might explain the algorithm better
Problem: i wrote the code compiler shows no error but when i run the code the program goes berserk, i guess may be some infinite loopig but i can't figure it out for the life of me. i use turbo c++ 4.5 so basically if anyone can look at the code and help me out it would be great . thanks in advance
Algorithm:
say we need to find lcm of 2,6,8
first we find the least of the series and add to it the number above it, i.e the series become
4,6,8
now we find the least value again and add to it the intitial value in the column i.e 2
6,6,8
so the next iteration becomes
8,6,8
8,12,8
10,12,8
10,12,16
12,12,16
14,12,16
14,18,16
16,18,16
18,18,16
18,18,24
20,18,24
20,24,24
22,24,24
24,24,24
as you can see at one point all numbers become equal which is our lcm
#include<iostream.h>
/*function to check if all the elements of an array are equal*/
int equl(int a[20], int n)
{
int i=0;
while(n==1&&i<20)
{
if (a[i]==a[i+1])
n=1;
else
n=0;
i++;
}
return n;
}
/*function to calculate lcm and return that value to main function*/
int lcm()
{
int i,k,j,check=1,a[20],b[20];
/*loading both arrays with numbers from 1 to 20*/
for(i=0;i<20;i++)
{
a[i]=i+1;
b[i]=i+1;
}
check= equl(a,1);
/*actual implementation of the algorith*/
while(check==0)
{
k=a[0]; /*looks for the least value in the array*/
for(i=0;i<20;i++)
{
if(a[i+1]<k)
{
k=a[i+1]; /*find the least value*/
j=i+1; /*mark the position in array */
}
else
continue;
}
a[j]=k+b[j]; /*adding the least value with its corresponding number*/
check= equl(a,1);
}
return (a[0]);
/*at this point all numbers in the array must be same thus any value gives us the lcm*/
}
void main()
{
int l;
l=lcm();
cout<<l;
}
In this line:
a[j]=k+b[j];
You use j but it is unitialized so it's some huge value and you are outside of the array bounds and thus you get a segmentation fault.
You also have some weird things going on in your code. void main() and you use cout without either saying std::cout or using namespace std; or something similar. An odd practice.
Also don't you think you should pass the arrays as arguments if you're going to make lcm() a function? That is int lcm(int a[], int b[]);.
You might look into using a debugger also and improving your coding practices. I found this error within 30 seconds of pasting your code into the compiler with the help of the debugger.
Your loop condition is:
while(n==1&&i<20)
So your equl function will never return 1 because if n happens to be 1 then the loop will just keep going and never return a 1.
However, your program still does not appear to return the correct result. You can split the piece of your code that finds the minimum element and replace it with this for cleanliness:
int least(int a[], int size){
int minPos = 0;
for(int i=0; i<size ;i++){
if (a[i] < a[minPos] ){
minPos = i;
}
}
return minPos;
}
Then you can call it by saying j = least(a, 20);. I will leave further work on your program to you. Consider calling your variables something meaningful instead of i,j,k,a,b.
Your equl function is using array indices from 0-20, but the arrays only have 1-19
j in lcm() is uninitialized if the first element is the smallest. It should be set to 0 at the top of the while loop
In the following code, when i=19, you are accessing a[20], which is out of the bounds of the array. Should be for(i=0;i<19;i++)
for(i=0;i<20;i++) {
if(a[i+1]<k)
You are not actually using the std namespace for the cout. this should be std::cout<<l
Your are including iostream.h. The standard is iostream without the .h, this may not work on such an old compiler tho
instead of hard-coding 20 everywhere, you should use a #define. This is not an error, just a style thing.
The following code does nothing. This is the default behavior
else
continue;
Hey, so basically I have this issue, where I'm trying to put an equation inside of a function however it doesn't seem to set the value to the function and instead doesn't change it at all.
This is a predator prey simulation and I have this code inside of a for loop.
wolves[i+1] = ((1 - wBr) * wolves[i] + I * S * rabbits[i] * wolves[i]);
rabbits[i+1] = (1 + rBr) * rabbits[i] - I * rabbits[i] * wolves[i];
When I execute this, it works as intended and changes the value of both of these arrays appropriately, however when I try to put it inside of a function,
int calcRabbits(int R, int rBr, int I, int W)
{
int x = (1 + rBr) * R - I * R * W;
return x;
}
int calcWolves(int wBr, int W, int I, int S, int R)
{
int x = ((1 - wBr) * W + I * S * R * R);
return x;
}
And set the values as such
rabbits[i+1] = calcRabbits ( rabbits[i], rBr, I, wolves[i]);
wolves[i+1] = calcWolves(wBr, wolves[i], I, S, rabbits[i]);
The values remain the same as they were when they were initialized and it doesn't seem to work at all, and I have no idea why. I have been at this for a good few hours and it's probably something that I'm missing, but I can't figure it out.
Any and all help is appreciated.
Edit: I realized the parameters were wrong, but I tried it before with the correct parameters and it still didnt work, just accidentally changed it to the wrong parameters (Compiler mouse-over was showing the old version of the parameters)
Edit2: The entire section of code is this
days = getDays(); // Runs function to get Number of days to run the simulation for
dayCycle = getCycle(); // Runs the function get Cycle to get the # of days to mod by
int wolves[days]; // Creates array wolves[] the size of the amount of days
int rabbits[days]; // Creates array rabbits [] the size of the amount of days
wolves[0] = W; // Sets the value of the starting number of wolves
rabbits[0] = R; // sets starting value of rabbits
for(int i = 0; i < days; i++) // For loop runs the simulation for the number of days
{
// rabbits[i+1] = calcRabbits ( rabbits[i], rBr, I, wolves[i]);
// // //This is the code to change the value of both of these using the function
// wolves[i+1] = calcWolves(wBr, wolves[i], I, S, rabbits[i]);
// This is the code that works and correctly sets the value for wolves[i+1]
wolves[i+1] = calcWolves(wBr, wolves[i], I, S, rabbits[i]);
rabbits[i+1] = (1 + rBr) * rabbits[i] - I * rabbits[i] * wolves[i];
}
Edit: I realized my mistake, I was putting rBr and wBr in as ints, and they were floats which were numbers that were below 1, so they were being automatically converted to be 0. Thanks sje
Phil I cannot see anything evidently wrong in your code.
My hunch is that your are messing up the parameters.
Using gdb at this point would be an over kill. I recommend you put print outs in calcRabbits and calcWolves. Print out all the parameters, the new value, and the iteration number. That will give you a good idea of what is going on and will help trace the problem.
Do you have the full code with initialization we could try to test and run?
I'm not sure this is the problem, but this is bad:
int wolves[days]; // Creates array wolves[] the size of the amount of days
int rabbits[days]; // Creates array rabbits [] the size of the amount of days
days is determined at runtime. This is nonstandard in c++ (and for large number of days could destroy your stack) you should only be using constants in array sizes. You can dynamically size a vector to workaround this limitation (or heap allocate the array).
Change to this:
std::vector<int> wolves(days);
std::vector<int> rabbits(days);
Or to this:
int *wolves = new int[days];
int *rabbits = new int[days];
// all your code goes here
delete [] wolves; // when you're done
delete [] rabbits; // when you're done
Which will dynamically allocate the array on the heap. The rest of the code should work the same.
Don't forget to #include <vector>, if you use the vector approach.
If you're still having problems, I would cout << "Days: " << days << endl; to make sure you're getting the right number back from getDays(). If you got zero, it would seem to manifest itself in "the loop not working".
I was using an integer as an argument for a double.