My program needs to compute a bounding box from a vector a boundary objects, and min/max 3d vectors of this bounding box need to be used in a CUDA kernel.
To do so i get my bounding box in a c++ routine (systemparticlesph.cpp) :
void SystemParticleSPH::computeNeighborhood()
{
//cellSize
UniformGridParameters grid_params;
grid_params.cellSize = sph_parameters.ParticleRadius;
//bbox
std::pair<glm::vec3, glm::vec3> bbox = CollisionObjectsContainer::getInstance()->getBBox();
grid_params.min = std::get<0>(bbox);
grid_params.max = std::get<1>(bbox);
//works fine here !
std::cout << "cpp cellSize " << grid_params.cellSize << std::endl;
std::cout << "cpp min " << grid_params.min.x << " " << grid_params.min.y << " " << grid_params.min.z << std::endl;
std::cout << "cpp max " << grid_params.max.x << " " << grid_params.max.y << " " << grid_params.max.z << std::endl;
//cuda call
computeNeighborsCuda(grid_params);
}
The results printed with cout are exactly what i expect according to the boundary objects i created :
cpp cellSize 0.02
cpp min -0.25 -0.25 -0.25
cpp max 0.25 0.25 0.25
I'm having a really hard time when i try to print the same exact data in the computeNeighborsCuda(grid_params); function located in systemparticlessph.cu :
void computeNeighborsCuda(UniformGridParameters grid_params)
{
printf("cellsize %g min %g %g %g max %g %g %g\n",grid_params.cellSize, grid_params.min.x, grid_params.min.y, grid_params.min.z, grid_params.max.x, grid_params.max.y, grid_params.max.z );
int numBlock = m_dPos.size()/256 + 1;
calcHashD<<<numBlock, 256>>>(thrust::raw_pointer_cast(&m_dGridParticleHash[0]), thrust::raw_pointer_cast(&m_dGridParticleIndex[0]), thrust::raw_pointer_cast(&m_dPos[0]), grid_params, m_dPos.size());
}
The results displayed (when i comment the 3 cout) should be the same but here is what i get :
cellsize -0,25 min -0,25 -0,25 0,25 max 0,25 0,25 -7168,19
It looks like there is some offset making the whole thing wrong : cellSize has the value of min.x, while max.z has an arbitrary value.
Note that the problem is exactly the same when i call printf from the CUDA kernel.
Also note that it is getting worse when i display both with cout and printf at the same time :
cpp cellSize 0.02
cpp min -0.25 -0.25 -0.25
cpp max 0.25 0.25 0.25
cellsize -1,79826e+36 min 0 1,21731e-37 0 max 1,21731e-37 0 1,21731e-37
Do you have any idea of to get the same result in the C function (and kernel) ?
Thanks in advance, this is really giving me a hard time.
Mathias
Edit :
Passing a reference instead of a copy of the structure, everything works perfectly fine.
Still, i have no idea why it does not work with a copy of the structure.
I would suggest to make your own struct with simple variables and copy the exact data you want to show from the c++ program into the CUDA function.
Related
Good day,
I am currently in the learning process of CGAL while being relatively new to C++. For my current project I need to use Minkowski sums and then do additional operations on the boundary of it.
However, before I do these additional operations I need to get a better understanding of the output of offset_polygon_2(), the exact Minkowski offset computation.
Question 1: What is the Syntax of the output for .outer_boundary?
From what I understand so far, it outputs a list of a conic circles defined here. I would also imagine you would need some kind of arc-angle range for each of these concic circles and origin point, correct? An example of the output goes something like this:
89 {-1*x^2 + -1*y^2 + 0*xy + 1400*x + 0*y + -489975} : (705,0) --ccw--> (700,5) {0*x^2 + 0*y^2 + 0*xy + 0*x + 0*y + 0} : (700,5) --l--> (699.97,5)...
Question 2: How do you use CGAL::draw() for the above?
I have the following code, but I am unsure of what else needs to be done before it can be drawn.
Offset_polygon_with_holes_2 offset = CGAL::offset_polygon_2(P, 5, traits);
double secs = timer.time();
std::cout << "The offset polygon has " << offset.outer_boundary().size()
<< " vertices, " << offset.number_of_holes() << " holes."
<< std::endl;
std::cout << "Offset computation took " << secs << " seconds." << std::endl;
Question 3: What other operations can be done on the "offset"?
So in the example code for Minkowski sums (also see above) offset.outer_boundary() is done, is there a list of other operations that can be done? Note: I do not think "operations" is the correct term here, please correct me.
I think that is all I have for now, thanks!
To get some more practice in C++, I decided to do some basic math functions without the aid of the math library. I've made a power and factorial function and they seem to work well. However, I'm having lots of problems regarding my Taylor Series cosine function.
Wikipedia Cosine Taylor Series
It outputs a good approximation at cos(1), cos(2), and begins losing precision at cos(3) and cos(4). Beyond that, its answer becomes completely wrong. The following are results from ./a.out
Input an angle in radians, output will be its cosine
1
Output is: 0.540302
Input an angle in radians, output will be its cosine
2
Output is: -0.415873
Input an angle in radians, output will be its cosine
3
Output is: -0.974777
Input an angle in radians, output will be its cosine
4
Output is: -0.396825 <-------------Should be approx. -0.654
Input an angle in radians, output will be its cosine
5
Output is: 2.5284 <-------------Should be approx. 0.284
Here is the complete source code:
#include <iostream>
#include <iomanip>
using std::cout;
using std::cin;
using std::endl;
int factorial(int factorial_input) {
int original_input = factorial_input;
int loop_length = factorial_input - 1;
if(factorial_input == 1 || factorial_input == 0) {
return 1;
}
for(int i=1; i != loop_length; i++) {
factorial_input = factorial_input - 1;
original_input = original_input * factorial_input;
}
return original_input;
}
double power(double base_input, double exponent_input) {
double power_output = base_input;
if(exponent_input == 0) {
return 1;
}
if(base_input == 0) {
return 0;
}
for(int i=0; i < exponent_input -1; i++){
power_output = power_output * base_input;
}
return power_output;
}
double cos(double user_input) {
double sequence[5] = { 0 }; //The container for each generated elemement.
double cos_value = 0; //The final output.
double variable_x = 0; //The user input x, being raised to the power 2n
int alternating_one = 0; //The (-1) that is being raised to the nth power,so switches back and forth from -1 to 1
int factorial_denom = 0; //Factorial denominator (2n)!
int loop_lim = sizeof(sequence)/sizeof(double); //The upper limit of the series (where to stop), depends on size of sequence. Bigger is more precision.
for(int n=0; n < loop_lim; n++) {
alternating_one = power(-1, n);
variable_x = power(user_input, (n*2));
factorial_denom = factorial((n*2));
sequence[n] = alternating_one * variable_x / factorial_denom;
cout << "Element[" << n << "] is: " << sequence[n] << endl; //Prints out the value of each element for debugging.
}
//This loop sums together all the elements of the sequence.
for(int i=0; i < loop_lim; i++) {
cos_value = cos_value + sequence[i];
}
return cos_value;
}
int main() {
double user_input = 0;
double cos_output;
cout << "Input an angle in radians, output will be its cosine" << endl;
cin >> user_input;
cos_output = cos(user_input);
cout << "Output is: " << cos_output << endl;
}
At five iterations, my function should maintain accuracy until after around x > 4.2 according to this graph on Desmos:
Desmos Graph
Also, when I set the series up to use 20 iterations or more (it generates smaller and smaller numbers which should make the answer more precise), the elements start acting very unpredictable. This is the ./a.out with the sequence debugger on so that we may see what each element contains. The input is 1.
Input an angle in radians, output will be its cosine
1
Element[0] is: 1
Element[1] is: -0.5
Element[2] is: 0.0416667
Element[3] is: -0.00138889
Element[4] is: 2.48016e-05
Element[5] is: -2.75573e-07
Element[6] is: 2.08768e-09
Element[7] is: -7.81894e-10
Element[8] is: 4.98955e-10
Element[9] is: 1.11305e-09
Element[10] is: -4.75707e-10
Element[11] is: 1.91309e-09
Element[12] is: -1.28875e-09
Element[13] is: 5.39409e-10
Element[14] is: -7.26886e-10
Element[15] is: -7.09579e-10
Element[16] is: -4.65661e-10
Element[17] is: -inf
Element[18] is: inf
Element[19] is: -inf
Output is: -nan
Can anyone point out what things I'm doing wrong and what I should be doing better? I'm new to C++ so I still have a lot of misconceptions. Thank you so much for taking the time to read this!
You have the following problems:
In the graph you are showing in the picture k is included in the sum, while you are excluding it in your code. Therefore k=5 in the Desmos graph is equal to double sequence[6] = { 0 } in your code.
This fixes the output for user_input = 4.
For user_input = 5 you can then compare to the graph to see that it gives a similar result as well (which is already far off of the true value)
Then you will have bugs for larger number of terms, because the factorial function outputs int, but the factorial grows so quickly that it will go out-of-range of the values int can hold quickly and also quickly out-of-range of any integer type. You should return double and let original_input be double as well, if you want to support a somewhat (though not much) larger input range.
In power you take the exponent as double, but work with it as if it was an integer. In particular you use it for the limit of loop iterations. That will only work correctly as long as the values are small enough to be exactly representable by double. As soon as the values become larger, the number of loop iterations will become inexact.
Use int as second parameter to power instead.
If one were to implement cos with this approach, one would normally use cos symmetry first, to reduce the range to something smaller, e.g. [0,pi/2] first, by using e.g. that cos(x + 2pi) = cos(x) and cos(x+pi) = - cos(x) and cos(-x) = cos(x), etc.
The problem comes from the factorial function you implemented.
I made minimal changes to your code and it runs fine for your example calculation of cos(1). Just #include <cmath> and replace factorial((n*2)) by tgamma(2*n+1). The output then reads
Input an angle in radians, output will be its cosine
Element[0] is: 1
Element[1] is: -0.5
Element[2] is: 0.0416667
Element[3] is: -0.00139082
Element[4] is: 2.48022e-05
Element[5] is: -2.75573e-07
Element[6] is: 2.08768e-09
Element[7] is: 4.65661e-10
Element[8] is: -4.65661e-10
Element[9] is: 4.65661e-10
Element[10] is: -4.65661e-10
Element[11] is: 4.65661e-10
Element[12] is: -4.65661e-10
Element[13] is: 4.65661e-10
Element[14] is: -4.65661e-10
Element[15] is: 4.65661e-10
Element[16] is: -4.65661e-10
Element[17] is: 4.65661e-10
Element[18] is: -4.65661e-10
Element[19] is: 4.65661e-10
Output is: 0.5403
This is the expected output for cos(1). For cos(n) with n>1 the problem is that the values for factorial_denom are getting to big for an integer. You should change the type to double: double factorial_denom. With your modified code I am getting the following results:
cos(1): Output is: 0.5403
cos(2): Output is: -0.416147
cos(3): Output is: -0.989992
cos(4): Output is: -0.653644
cos(5): Output is: 0.283662
Run your modified code online.
In addition to the changes already suggested, consider limiting the use of the series to a relatively narrow range of inputs. There are numerical problems you can encounter for very large angles, and they increase the amount of testing you need to do.
The cosine function has several identities, such as cos(x) = cos(-x) and cos(x) = cos(n*2*pi+x) for any integer n. Use these to reduce the angle to a limited range before running your series solution.
I'm using Eigen library in C++ and I'm trying to find the determinant of a matrix. I'm getting different results depending on how I initialize the matrices.
Method I:
MatrixXd a(3, 3);
for (int n = 0; n < 3; n++)
for (int m = 0; m < 3; m++)
a(n,m) = (double) (n + m*m + 2.5)/3;
cout << "Matrix a: " << endl;
cout << a << endl;
cout << "Determinat of matrix a is: " << a.determinant() << endl;
This part of the code prints
Matrix a:
0.8333333 1.166667 2.166667
1.166667 1.5 2.5
1.5 1.833333 2.833333
Determinat of matrix a is: -7.401487e-17
Method II:
MatrixXd b(3, 3);
b << 0.8333333, 1.166667, 2.166667,
1.166667, 1.5, 2.5,
1.5, 1.833333, 2.833333;
cout << b;
cout << endl << "Determinant of matrix b is: " << b.determinant();
which prints
0.8333333 1.166667 2.166667
1.166667 1.5 2.5
1.5 1.833333 2.833333
Determinant of matrix b is: 2.333331e-07
Method I produces the wrong result while Method II gives the right answer. What's going wrong in the first case? (I'm using Visual Studio.) Thanks in advance!
What you are observing here are rounding errors in your calculations. Let me explain it like this:
For a computer, everything is based on the binary number system, i.e. instead of base 10 like we mostly use in our everyday lives, computers calculate with base 2, i.e. only the digits 0 and 1.
This not only applies to integers, but also to real numbers like 0.83333...
But just like it is impossible to write all digits of 0.83333..., your computer cannot store every last digit of the binary representation of this number - thus it has to round the result somehow.
Depending on how you initialize it (either by computing (n + m*m + 2.5)/3 or by reading the value from your comma-initialization), the result might be slightly different in one of the last digits, thus leading to different results.
You can try this out by comparing 0.8333333 with 2.5/3, which will probably return false. If you print the numbers, you get the same result, but the internal representation differs ever so slightly.
However you should note that the absolute error itself is quite small (smaller than 0.000001), so you don't need to worry about it at the moment.
If you want exact results, it might be helpful to switch to a rational number type which can represent these values exactly.
I am asked, after giving me
an initial_population(7),
a growth_rate(1.2%),
an initial_year (2011), and a formula that link the final population to the inital one with the following :
initial_population * exp ( (final_year - initial_year) * (rate/ 100.0))
For a certain population entered, I have made this population grow year after year with this following forumla :
double pc(0.0); // pc = population entered
while (pc <= initial_population)
{
cout << "How many billion (> 7) ? ";
cin >> pc;
};
int temp(year);
do {
++temp;
cout << "Population in " << temp << " : " <<
initial_population * exp ( (final_year - initial_year) * (rate/ 100.0))
<< endl;
}
while ( pc > initial_population *
exp ( (final_year - initial_year) * (rate/ 100.0)));
I would like now to make this population growth_rate being divided by two anytime the initial population doubles and to make it show until the population has reached the entered population "pc". Obviously, the process must take longer than when the growth_rate wasn't divided and the outcome should look like :
Population in 2012 : 7.085 ; growth rate : 1.2 %
Population in 2013 : 7.17 ; growth rate : 1.2 %
Population in 2014 : 7.257 ; growth rate : 1.2 %
Population in 2015 : 7.344 ; growth rate : 1.2 %
...
Population in 2068 : 13.87 ; growth rate : 1.2 %
Population in 2069 : 14.04 ; growth rate : 0.6 %
Population in 2070 : 14.12 ; growth rate : 0.6 %
...
Population en 2195 : 29.02 ; growth rate : 0.3 %
All I know in C++ yet is until the for and do while loops, with of course the if else statements.
Is there anyonone who can help me with that, I don't need to have the perfect answer, just some help on how to start with this part. for example how to make the statement when the population doubles, etc.. ?
Thanks a lot.
Save the initial_population value, multiplied by 2, in a separate variable. Then check on each iteration if the current_population (a variable I made up, but it's value should be obvious) is greater than or equal to the other stored variable, multiply the value by 2 again and split the growth rate in half. Something like this:
double population_doubled_check_val = initial_population * 2;
double current_population;
do {
++temp;
current_population = initial_population * exp ( (final_year - initial_year) * (rate/ 100.0));
cout << "Population in " << temp << " : " << current_population << endl;
if (current_population >= population_doubled_check_val) {
population_doubled_check_val *= 2;
rate /= 2;
}
}
while ( current_population < pc );
I don't think copypasta of that will work, but it should give you an idea. On an aside, it's helpful if you provide a full, minimum implementation necessary to exemplify the problem but still compiles. For no other reason than to get answers faster. :)
I am having trouble getting this program to output properly. It simulates a drunken sailor on a board that randomly goes one step to the left or right. At the end of the simulation, the program outputs the percentage of times he fell off the board vs not falling off. My percentage is always zero, and I can't figure out whats wrong with my code.
This function correctly outputs the "experiments" and "fallCount" variable, but always displays "fallCount / experiments" as zero.
This should read "After 2 experiments, sailor fell 1 time, fall percentage was 0.5%"
(if experiments = 2 and fallCount = 1) instead, its 0% every time.
Let me know what I am doing wrong. Thank you!
void outputExperimentStats(int experiments, int fallCount)
{
cout << "After " << experiments << " experiments, sailor fell "
<< fallCount << " time, fall percentage was " << fallCount / experiments << "%\n";
}
That is because you are using integer division. There are no decimals, so things get truncated. E.g.
1 / 2 --> 0 // integer division
This is correct, and expected behavior.
To get the behavior you want, use double or float.
1.0 / 2.0 --> 0.5 // double division
In your example, you can either change the types of your inputs to double or if you want to keep them int, you can convert them during the division
static_cast<double>(fallCount) / static_cast<double>(experiments)