Saving an array value into a double variable - c++

Greetings everyone. Having an issue compiling my script containing the following function. Three errors occur, all on the same line where I set distance += to distances [][]:
error C2108: subscript is not of integral type
error C2108: subscript is not of integral type
error C2297: '+=' : illegal, right operand has type 'double (*)[15]'
Assistance would be much appriciated.
double S_initial;
double distances [15][15];
double order [15];
void Initialize()
{
double x, y ,z;
double distance = 0;
for (int i = 0; i <= 14; i++)
{
x = order [i];
y = order [i + 1];
distance += distances [x][y];
}
S_initial = distance;
}

Well, the array subscripts x and y are not of an integral type like int, but of type double:
double x, y, z;
...
distance += distances[x][y];
And something like the 1.46534th element of an array doesn't make sense, so the compiler complains.

x and y are not integers... You need to pass integers as array subscripts.

Stop using double and use int instead.
Or if you have to use double in the order array, you need to decide how to round any non-integer value that may be found in order to a int. Math.Floor, Math.Ceiling etc.

You cannot use floating point numbers to index into arrays. Use int or even better size_t.
for (int i = 0; i <= 14; i++)
{
x = order [i];
y = order [i + 1]; /* when i = 14, you invoke UB */
distance += distances [x][y];
}
On to the second part:
double order [15];
is uninitialized and hence invokes UB, when used.

Related

The average of an array in float format

How i get the float result of the division?
Although i defined the average array as float.
int main()
{
const int Number = 20;
int Fibonacci[Number];
float average[Number];
for ( int i =0; i <= Number; i++ )
{
if ( i == 0 )
{Fibonacci[i] = 0;}
else if ( i == 1 )
{Fibonacci[i] = 1;}
else
{Fibonacci[i] = Fibonacci[i -1] + Fibonacci[i -2];
//average[i] = (Fibonacci[i -1] + Fibonacci[i -2])/2 ;
}
}
cout<< "The first 20 Fibonacci series numbers are: \n";
for ( int i = 1; i <= Number; i++)
{ cout<< Fibonacci[i]<<endl;
}
cout<< "The average adjacent array numbers are: \n";
for ( int i = 3; i <= Number; i++)
{ average[i] = (Fibonacci[i]/2);
//cout.precision(0);
Here the proplem
cout<< average[i]<<endl; <-----here the problem!!
}
return 0;
}
I appreciate any help.
Thanks in advance.
When you do the division, you are doing an integer division, so you won't get floating point results. A simple fix would be the following:
average[i] = Fibonacci[i] / 2.0f;
Note that if one of the operands to / is a float, then you get floating point division.
Also, note that your loops index too far into the array. You need to stop before Number, like this:
for ( int i = 0; i < Number; i++)
This is because valid array indexes go from 0 .. (Number - 1).
If Fibonacci[i] is of type int, then (Fibonacci[i]/2) is an integral division, resulting in an integral value (without any fractional part). Assigning this integral result to a float does not change the fact that you have performed an integral division.
You can enforce a floating point division by making one of the operands a floating point value.
So (1) use either a cast...
((float)Fibonacci[i])/2
or (2) divide by 2.0f (which is a float value):
Fibonacci[i]/2.0f
Just use typecasting the fibonacci array like this-
average[i] = (float)Fibonacci[i]/2;
Because in order to get float result any of the two variable used in / operation has to be float.

Writing a monte carlo integration program and I don't why im getting certain errors

I am writing a monte carlo program to do a 10D integral. But what I have started off with is trying to get the full method to work in a lower dimension before moving up to the higher level. Anyways I have this program and it is using the the struct random number generator given in Numerical Recipes. Now when I run a program and just outputs the the random number it works fine, and the same when I use the built in rand function for the actual integration as well. The problem is that when I combine the two I get that the way I call the RNG struct it says that I am using 'of undeclared identifier' for both instances that I am trying to call this struct. I honestly have no idea why its throwing this error and how to fix it. Any suggestions would be greatly appreciated. The code that I am referencing is here and the error is stated as
Montetest.cpp:50:17: error: use of undeclared identifier 'rndvar'
double u1 = rndvar.int64();
Montetest.cpp:51:17: error: use of undeclared identifier 'rndvar'
double u2 = rndvar.int64();"
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using namespace std;
struct Ran {
/*
Implementation of the highest quality recommended generator. The constructor
is called with
an integer seed and creates an instance of the generator. The member
functions int64, doub,
and int32 return the next values in the random sequence, as a variable type
indicated by
their names. The period of the generator is roughly 3.138 x 10^57.
*/
unsigned long u,v,w;
Ran(unsigned long j) : v(4101842887655102017LL), w(1) {
// Constructor. Call with any integer seed (except value of v above).
u = j ^ v; int64();
v = u; int64();
w = v; int64();
}
inline unsigned long int64() {
// Return 64-bit random integer.
u = u * 2862933555777941757LL + 7046029254386353087LL;
v ^= v >> 17; v ^= v << 31; v ^= v >> 8;
w = 4294957665U*(w & 0xffffffff) + (w >> 32);
unsigned long x = u ^ (u << 21); x ^= x >> 35; x ^= x << 4;
return (x + v) ^ w;
}
inline double doub() { return 5.42101086242752217E-20 * int64(); }
// Return random double-precision floating value in the range 0. to 1.
inline unsigned int int32() { return (unsigned int)int64(); }
// Return 32-bit random integer.
};
//int count;
double total, inBox;
// user defined function below
double f (double x){
return exp(cos(x));
}
//
//function to calculate a definite integral given bounds of integration
(xmin/max) & bounds of function (ymin/ymax)
double integral (double (*f)(double), double xmin, double xmax, double ymin,
double ymax,int n){
for (int count=0; count < n; count++){
double u1 = rndvar.int64();
double u2 = rndvar.int64();
double xcoord = ((xmax - xmin)*u1) + xmin;
double ycoord = ((ymax - ymin)*u2) + ymin;
double val = f(xcoord);
total++;
if (val > ycoord){
inBox++;
}
}
double density = inBox/total;
std::cout<<(xmax - xmin)*(ymax - ymin)*density<<std::endl;
}
int main (int argc, char **argv)
{
if(argc != 3) {
printf("Need 2 arguments: seed n\n");
exit(0);
}
unsigned long iseed=atol(argv[1]);
int n=atoi(argv[2]); // number of steps
vector <int> test;
Ran rndvar(iseed);
cout<< "RESULT: " <<endl;
integral(f,-2,2,0,4,n);
}
rndvar is declared in main but used in integral function.
Pass rndvar to integral function, or declare it in integral function, or make it a global variable (generally not recommended).
In C++11 you do not need to implement your own pseudo-random number generators. You can use the standard ones, see the example in pseudo-random number generation.
Correct me if I am wrong but I think the problem is that your rndvar is declared and initialized outside of your integral function. This means that integral() has no knowledge of rndvar because it is outside of integral()'s scope.
Try passing in rndvar as a parameter to integral() I believe that will fix your issue.

How to multiply a number by a function passed by reference

I have the following code above my main method and all my other functions:
typedef double (*FUNC)(double);
double integrate(FUNC f, double a, double b){
double sum = 0;
for(int i=a; i<=b; i++){
sum = sum + (f * .0001); //error occurs here, red squiggly line under "f"
}
return sum;
}
In the Microsoft Visual Studio C++ compiler, I get an error: Expression must have arithmetic or enum type. I pointed out where the error comes from above in a comment. Can someone explain to me why I have this error and how I can resolve this error?
I take it you are trying to integrate f(x) for values of x from a to b?
In which case your code is quite incorrect.
Your 0.0001 seems to indicate that you are actually trying to use 10000 steps, in which case you would use something along the lines of:
const int steps = 10000;
double x = a;
double delta = (b - a) / steps;
for(int i = 0; i < steps; i++, x += delta)
You would then calculate use a call f(x) to call the function pointer, and sum that up.
Try using this instead
sum = sum + f(.0001);
Multiplying a function pointer by a fraction would not go so well.

expression must have pointer to function type

I'm fairly new to C++ and I'm attempting to learn how to use pointers. I have the following file that creates coordinates and then moves them in random directions using a random number generator.
The value sigmaf_point is inputted from a text file:
void methane_coords(double *&sigmaf_point)
double dummy_int = 1;
string dummystring;
string s;
ifstream Dfile;
std::stringstream out;
out << 1;
s = out.str() + ".TXT";
Dfile.open (s.c_str());
if (Dfile.fail())
{
return;
}
for (int i=0; i<dummy_int; i++)
{
Dfile >> sigmaf_point[i];
}
Which I then use in another function:
double initial_energy(double **coords_fluid, const double *box_size){
// Loop over all pairs of atoms and calculate the LJ energy
double total_energy = 0;
for (int i = 0; i <= n_atoms-1; i++)
{
sf1=sigmaf_point(coords_fluid[i][3]);
ef1=epsilonf_point(coords_fluid[i][3]);
// Energy fluid-fluid
for (int j = i+1; j <= n_atoms-1; j++)
{
sf2=sigmaf_point(coords_fluid[j][3]);
ef2=epsilonf_point(coords_fluid[j][3]);
double delta_x = coords_fluid[j][0] - coords_fluid[i][0];
double delta_y = coords_fluid[j][1] - coords_fluid[i][1];
double delta_z = coords_fluid[j][2] - coords_fluid[i][2];
// Apply periodic boundaries
delta_x = make_periodic(delta_x, box_size[0]);
delta_y = make_periodic(delta_y, box_size[1]);
delta_z = make_periodic(delta_z, box_size[2]);
// Calculate the LJ potential
s=(sf1+sf2)/2.0;
e=pow((ef1*ef2),0.5);
double r = pow((delta_x*delta_x) + (delta_y*delta_y) +
(delta_z*delta_z),0.5)/s;
double e_lj = 4*((1/pow(r,12.0))-(1/pow(r,6.0))/e);
total_energy = (total_energy + e_lj);
}
}
coords_fluid is created in the main file like so:
double **coords_fluid = new double*[5000];
Now the problem is with sf1=sigmaf_point(coords_fluid[i][3]);
I get the error "expression must have pointer to function type" for sigmaf_point. I'm a bit confused about this, I know it's about how I call the variable but can't seem to fix it.
Cheers
First of all: Rereference to pointers are completly useless since it a pointer is already a sort of reference.
So change double *& to double * or double &. It will be faster.
Besides I see that you're using sigmaf_point as a function and as an array.
Which one is it?
Could you give the declaration of sigmaf_point?
Assuming it's an array change
sf1 = sigmaf_point(coords_fluid[i][3]);
to
sf1 = sigmaf_point[coords_fluid[i][3]];

Need help understanding passing arguments to function

I’m new to C++ and unsure about how to pass arguments to functions.
I’m using a function Distance() to calculate the distance between two nodes.
I declare the function like this:
int Distance(int x1, int y1, int x2 , int y2)
{
int distance_x = x1-x2;
int distance_y = y1- y2;
int distance = sqrt((distance_x * distance_x) + (distance_y * distance_y));
return distance;
}
In the main memory I have 2 for loops.
What I need to know is if I can pass the values like this: Distance (i, j, i+1, j+1).
for(int i = 0; i < No_Max; i++)
{
for(int j = 0; j < No_Max; j++)
{
if(Distance(i, j, i+1, j+1) <= Radio_Range) // the function
node_degree[i] = node_degree[i] + 1;
cout << node_degree[i] << endl;
}
}
Arguments to functions can be supplied as any expression which matches the type of that argument or can be cast to it.
Tips :
You should use double instead of int if you want to use sqrt :
http://www.cplusplus.com/reference/clibrary/cmath/sqrt/
It looks as if you are calling your Distance(int, int, int, int) function correctly.
The following statement will call Distance():
Distance (i, j, i+1, j+1);
This will store the value returned by Distance() in a variable:
int dist = Distance (i, j, i+1, j+1);
This will compare the value returned by Distance() (the left operand) to Radio_Range (the right operand). If the left operand is less than or equal to the right operand, it will be evaluated to 1 (true). Otherwise it will be 0 (false). If the overall value of the expression inside the if statement is non-zero, the statement or block immediately following the if statement will be executed:
if(Distance(i, j, i+1, j+1) <= Radio_Range)
//Statement;
or:
if(Distance(i, j, i+1, j+1) <= Radio_Range){
//Statement;
//Statement;
//...
}
However, the value returned by Distance() will be truncated to an integer. Thus, distance will not equal the actual distance unless (distance_x * distance_x) + (distance_y * distance_y) is a perfect square. For better precision, consider using a double. If you intend to have the function return an int, it would be wise to do an explicit type cast, e.g.:
int distance = (int)sqrt((distance_x * distance_x) + (distance_y * distance_y));
This will ensure that if you or anyone else looks at the code later on, they will not think the function is using the wrong data type.