Double not being printed out - c++

In this code, I am making a cluster of particles and assigning them x, y and z coordinates. Then, I am evaluating the force due to this cluster at some far away point. The function directSumUnregularized calculates that force.
I want to see what that force is, but for whatever reason, it is not being printed out.
This is my code:
#include <omp.h>
#include <time.h>
#include <iostream>
#include <cmath>
#include <random>
#include "unitTestFunctions.h"
int main() {
//set up cluster of particles
const int numberOfParticles = 10;
std::random_device rd{};
std::mt19937 gen{rd()};
std::normal_distribution<> d{0,1};
PARTICLE *clusterOfParticles = new PARTICLE [numberOfParticles];
double sumX{}, sumY{}, sumZ{};
for (int ind=0; ind<numberOfParticles; ind++){
clusterOfParticles[ind].x = d(gen);
clusterOfParticles[ind].y = d(gen);
clusterOfParticles[ind].z = d(gen);
}
//test position
double xTest {5}, yTest{6}, zTest {7};
double *exactForceX{nullptr}, *exactForceY{nullptr}, *exactForceZ{nullptr};
*exactForceX = 0;
*exactForceY = 0;
*exactForceZ = 0;
directSumUnregularized(numberOfParticles, exactForceX, exactForceY,
exactForceZ, xTest, yTest, zTest,
clusterOfParticles);
std::cout<<"exactForce X: "<<*exactForceX<<std::endl;
delete [] clusterOfParticles;
return 0;
}
and my function:
#include <omp.h>
#include <time.h>
#include <iostream>
#include <cmath>
#include <random>
#include "unitTestFunctions.h"
void directSumUnregularized(const int numberOfParticles, double *exactForceX,
double *exactForceY, double *exactForceZ, double xTest, double yTest, double zTest,
PARTICLE *clusterOfParticles){
double rSq{};
double r{};
double dx {}, dy {}, dz{};
const double pi = 3.1415926535897;
double inv4pi = 1/(4*pi);
for (int i=0; i<numberOfParticles; i++){
dx = xTest - clusterOfParticles[i].x;
dy = yTest - clusterOfParticles[i].y;
dz = zTest - clusterOfParticles[i].z;
rSq = dx*dx+dy*dy+dz*dz;
r = sqrt(rSq);
*exactForceX -= inv4pi*(dx/(rSq*r));
*exactForceY -= inv4pi*(dy/(rSq*r));
*exactForceZ -= inv4pi*(dz/(rSq*r));
}
return;
}
how should I go about this?

Regarding exactForceX/Y/Z, in order to work, it has to be like this:
//test position
double xTest = 6, yTest = 6, zTest = 7;
double exactForceX = 0, exactForceY = 0, exactForceZ = 0;
directSumUnregularized(umberOfParticles, &exactForceX, &exactForceY,
&exactForceZ, xTest, yTest, zTest,
clusterOfParticles);
std::cout << "exactForce X: " << exactForceX << std::endl;
1st, define (& initialize) the 3 variables:
double exactForceX = 0, exactForceY = 0, exactForceZ = 0;
2nd, deliver the 3 addresses to the function, to allow it to store the results.

The problematic section is
double *exactForceX{nullptr}, *exactForceY{nullptr}, *exactForceZ{nullptr};
*exactForceX = 0;
*exactForceY = 0;
*exactForceZ = 0;
What exactly is this doing?
double *exactForceX{nullptr};
*exactForceX = 0;
You are creating a pointer with the value of nullptr, attempting to dereference it and assign the value 0. Dereferencing a nullptr is undefined behaviour.
To fix it you need the address-of operator &
double exactForceX = 0;
double exactForceY = 0;
double exactForceZ = 0;
directSumUnregularized(numberOfParticles, &exactForceX, &exactForceY,
&exactForceZ, xTest, yTest, zTest,
clusterOfParticles);
It seems that there is some confusion on how pointers work. I like to use a simple example like this.
double value = 12345;
double *pointer_to_value = &value;
std::cout << "value " << value << std::endl;
std::cout << "&value " << &value << std::endl;
std::cout << "pointer_to_value " << pointer_to_value << std::endl;
std::cout << "*pointer_to_value " << *pointer_to_value << std::endl;
This will give the output that looks like: (The address may be different for you)
value 12345
&value 0x7ffc601869b0
pointer_to_value 0x7ffc601869b0
*pointer_to_value 12345
The point (heh) is that a pointer must point to a valid location. That is, either the location of a variable, or a call to new. In this case, the valid location is the location of the variable value.
See also: What is a segmentation fault?

Related

No matching function for call to a member function in class

I am new to C++ and trying to make a program to calculate bond price, the original code works well but I have difficulties transferring it to OOP. mode. The program uses two arrays and a integer to do calculation. I used a loop in constructor to initialize data members (learned from stack over flow). it looks fine but I experienced one error like: no matching function for call to member function. the data can't be passed to member function. I was trapped here a whole day. Could anybody give me some insights? Thank you. The code follows:
#include <array>
#ifndef DRAFT_H
#define DRAFT_H
class Draft
{
public:
Draft(int, double [], double[]);
double F (double);
void Bcalculator (int, double[], double[]);
void printResult();
void printDfactor();
private:
double discF[3]{};
double bPrice {0};
double bDuration {0};
double bConvexity {0};
double term[3];
double cFlow[3];
int sizeofArray;
private:
};
#endif // DRAFT_H
#include "Draft.h"
#include <iostream>
#include <cmath>
#include <array>
#include <iomanip>
using namespace std;
Draft::Draft( int arraySize, double termArr[], double cFlowArr[]):sizeofArray{arraySize}{
for (int i = 0; i < 3; i++){
term[i] = termArr[i];
cFlow[i] = cFlowArr[i];}
}
double Draft::F (double x){
return 0.05 / (1 + exp(-pow((1 + x),2)));
}
void Draft::Bcalculator(int sizeofArray, double term[], double cFlow[]){
double a = 0;
int n = 16;
for (int k =0; k < sizeofArray; k++){
double h = (term[k] - a)/n;
double x[n], fx[n];
for (int i = 0; i <= n; i++){
x[i] = a + i * h;
fx[i] = F(x[i]);
}
double result = 0;
double discF[]{};
for (int i = 0; i <= n; i ++){
if (i == 0 || i == n){
result += fx[i];
}
else if (i % 2 != 0){
result += 4 * fx[i];
}
else {
result += 2 * fx[i];
}
}
result = result * (h/3);
discF[k] = exp (- result);
bPrice += discF[k] * cFlow[k];
bDuration += term[k] * cFlow[k] * discF[k];
bConvexity += pow(term[k], 2) * cFlow[k] * discF[k];
}
bDuration = bDuration / bPrice;
bConvexity = bConvexity / bPrice;
}
void Draft::printDfactor(){
for (int k = 0; k < sizeofArray; k++) {
cout << k + 1 << setw (20) << discF[k] << endl;
}
}
void Draft::printResult()
{
cout << "Bond Price = " << setw(20) << bPrice << endl;
cout << "Bond duration = " <<setw(20) << bDuration <<endl;
cout << "Bond Convexity = " << setw(20) << bConvexity << "\n";
}
#include "Draft.h"
#include <iostream>
#include <cmath>
#include <array>
#include <iomanip>
using namespace std;
int main (){
double termArray[3]{1, 2, 3};
double cFlowArray[3]{5, 5, 105};
int arraySize = 3;
Draft bond1 (arraySize, termArray, cFlowArray);
Draft::Bcalculator();
bond1.printResult();
bond1.printDfactor();
return 0;
}
The error is:
main.cpp|20|error: no matching function for call to
'Draft::Bcalculator include\Draft.h|18|note: candidate: 'void
Draft::Bcalculator(int, double*, double*)'| include\Draft.h|18|note:
candidate expects 3 arguments, 0 provided|
There are two problems in your code.
Definition does not match call. You defined Bcalculator as:
void Draft::Bcalculator(int sizeofArray, double term[], double cFlow[])
But then you call it without arguments:
Draft::Bcalculator();
To be able to call Draft::Bcalculator() you need to add static in the definition:
static void Draft::Bcalculator(int sizeofArray, double term[], double cFlow[])
If you do not want to make it static, call it the normal way, i.e. Draft d{...}; d.Bcalculator().
EDITED
I realized that Bcalculator is using the same three parameters you use to construct and store in Draft class. Therefore, you should call Bcalculator without any arguments and use the class members termArray, cFlowArray and arraySize:
int main ()
{
double termArray[3]{1, 2, 3};
double cFlowArray[3]{5, 5, 105};
int arraySize = 3;
Draft bond1 (arraySize, termArray, cFlowArray);
bond1.Bcalculator();
bond1.printResult();
bond1.printDfactor();
return 0;
}
Then, your definition and implementation of this function has to be changed accordingly:
class Draft
{
public:
...
void Bcalculator(); // <- remove parameters in this definition
private:
double term[3];
double cFlow[3];
int sizeofArray;
}
void Draft::Bcalculator() // <- remove parameters in this implementation
{
... // use automatically the private members term, cFlow and sizeofArray
}
This code works, I compiled it.
Regards!

How can I align the numbers that the console outputs at the same position

I'm trying to write a very simple C++ program which outputs a lookup table with the corresponding x and y values of sinus function. The code that I wrote is the following:
#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double hw = 4.0;
int nsteps = 30;
const double PI = 3.14159;
const double maxx = hw * PI;
const double deltax = maxx / nsteps;
double x = 0.0;
for (int i = 0; i < nsteps; i++) {
const double f = sin(x);
cerr << x << "\t" << f << endl;
x = x + deltax;
}
return 0;
}
Now the program is working, but my problem is, that the values are not getting aligned properly as showed in the following picture
So is there any way, to achieve that the second column of the values will actually be a column and all the values are aligned at the same position? What could I use instead of \t?
The above answer provides an incorrect solution because the alignment is not set correctly. I would use a function to handle the formatting:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
void printxy(double x, double y, int width){
cout << setw(width) << x << "\t";
if (y < 0) cout << "\b";
cout << setw(width) << y << "\n";
}
int main(){
double hw = 4.0;
int nsteps = 30;
const double PI = 3.14159;
const double maxx = hw * PI;
const double deltax = maxx / nsteps;
double x = 0.0;
int decimals = 6;
int width = 8; //Adjust as needed for large numbers/many decimals
cout << std::setprecision(decimals);
cout << std::setw(width);
cout.setf(ios::left);
for (int i = 0; i < nsteps; i++) {
const double y = sin(x);
printxy(x, y, width);
x = x + deltax;
}
}
The output is now formatted correctly:
0 0
0.418879 0.406736
0.837757 0.743144
1.25664 0.951056
1.67551 0.994522
2.09439 0.866026
2.51327 0.587787
2.93215 0.207914
3.35103 -0.207909
3.76991 -0.587783
4.18879 -0.866024
4.60767 -0.994521
5.02654 -0.951058
5.44542 -0.743148
5.8643 -0.406741
6.28318 -5.30718e-06
6.70206 0.406731
7.12094 0.743141
7.53982 0.951055
7.95869 0.994523
8.37757 0.866029
8.79645 0.587791
9.21533 0.207919
9.63421 -0.207904
10.0531 -0.587778
10.472 -0.866021
10.8908 -0.994521
11.3097 -0.951059
11.7286 -0.743151
12.1475 -0.406746
I would also discourage the use of cerr for these kinds of printing operations. It is intended for printing errors. Use cout instead (it works the same way for all practical purposes).
I should also mention that endl is a ticking bomb: it flushes the output, meaning that the internal buffer of the stream is written out (be it the console, a file or whatever). When applications scale and become more IO intensive, this can become a significant performance problem: the buffer that is intended to increase the IO performance is potentially unused due to frequent endl insertions. The solution is to use the newline character '\n'.
Use std::setprecision() to set count number for decimal after point, and std::setw() to set width of output length. Include <iomanip> needed, example:
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
double hw = 4.0;
int nsteps = 30;
const double PI = 3.14159;
const double maxx = hw * PI;
const double deltax = maxx / nsteps;
double x = 0.0;
cerr << std::setprecision(8);
for (int i = 0; i < nsteps; i++) {
const double f = sin(x);
cerr << std::setw(20) << x << std::setw(20) << f << endl;
x = x + deltax;
}
return 0;
}
Output is:
0 0
0.41887867 0.40673632
0.83775733 0.74314435
1.256636 0.95105619
1.6755147 0.99452204
2.0943933 0.86602629
2.513272 0.58778697
2.9321507 0.20791411
3.3510293 -0.20790892
3.769908 -0.58778268
4.1887867 -0.86602363
//...

Geometric Brownian Motion; Simulation of Stock Price

I made a GBM function in C++ and I believe I am getting too much of a range of stock prices when I start with an initial price of 100 the output can be from [50,400]. I am not sure what I am doing wrong in my code, I am guessing there is something wrong with the way I seed the random standard normal numbers. Please have a look at the function and let me know if there is anything I shold modify or change.
Here is the function:
std::vector<double> GBM(const int M, const int N, const double T, const double r, const double q, const double sigma, const double S0){
double dt = T/N;
std::vector<double> Z;
std::vector<double> S;
S.push_back(S0);
std::mt19937 e2(time(0));
std::normal_distribution<double> dist(0.0, 1.0);
for(int i = 0; i < M; i++){
Z.push_back(dist(e2));
}
double drift = exp(dt*((r - q)-0.5*sigma*sigma));
double vol = sqrt(sigma*sigma*dt);
for(int i = 1; i < M; i++){
S.push_back(S[i-1] * drift * exp(vol*Z[i]));
}
return S;
}
Here is the main.cpp file that utilizes the function above:
#include <iostream>
#include "LSM.h"
#include <cmath>
#include <ctime>
#include <Eigen/Core>
#include <Eigen/SVD>
#include <iostream>
#include <vector>
#include <random>
std::vector<double> GBM(const int M, const int N, const double T, const double r, const double q, const double sigma, const double S0);
int main(){
const double r = 0.04; // Riskless interest rate
const double q = 0.0; // Divident yield
const double sigma = 0.20; // Volatility of stock
const double T = 1; // Time (expiry)
const int N = 1000; // Number of time steps
const double K = 100.0; // Strike price
const double S0 = 100.0; // Initial stock price
const int M = 10000; // Number of paths
const int R = 2; // Choice of basis for Laguerre polynomial
//LSM Option_value(r,q,sigma,T,N,K,S0,M,R);
std::vector<double> s = GBM(M,N,T,r,q,sigma,S0);
for(int i = 0; i < M; i++){
std::cout << s[i] << std::endl;
}
return 0;
}
A typical output that one should get starting with an initial stock price of 100 is below:
153.5093
132.0190
96.2550
106.5196
58.8447
135.3935
107.1194
101.2022
134.2812
82.2146
87.9162
74.9333
88.9137
207.5150
123.7893
95.8526
120.0831
96.3990
103.3806
113.8258
100.6409
92.0724
81.1704
121.9925
114.3798
117.8366
86.1070
74.4885
82.6013
78.0202
97.0586
119.7626
89.0520
72.2328
92.1998
84.7180
138.9160
91.0091
105.2096
91.3323
79.0289
115.9377
75.4887
123.2049
101.1904
95.9454
82.4181
108.8314
123.0198
76.8494
94.8827
149.5911
95.6969
143.3498
87.0939
77.3033
105.8185
122.3455
79.8208
112.9913
120.1649
131.3052
136.8246
96.5455
109.0187
87.1363
103.1835
106.3896
143.9496
119.1357
99.9114
111.1409
79.0563
147.1506
105.7851
99.7089
117.8770
99.7602
73.1796
125.8698
109.4367
135.5020
88.1979
129.8502
121.1233
76.7520
86.5296
118.6721
83.2511
116.3950
99.8795
70.6895
64.9578
111.4750
102.6343
82.8765
90.3479
106.8873
106.3850
119.3399
Function GBM should simulate 1 path every time. So no need to supply M. And the path length is, in your code, defined by N instead of M.
If you implement this change, GBM return the whole simulated path.
Then you need to call GBM M times in order to calculate all the simulations.
Also there is no need to store all the random numbers generated.
Based on your sample, something like this:
#include <iostream>
#include <vector>
#include <random>
// Random generator initialize (only once).
static std::mt19937 rng(time(0));
std::vector<double> GBM(const int N, const double T, const double r,
const double q, const double sigma, const double S0)
{
double dt = T/N;
std::vector<double> S;
S.push_back(S0);
std::normal_distribution<double> dist(0.0, 1.0);
double drift = exp(dt*((r - q)-0.5*sigma*sigma));
double vol = sqrt(sigma*sigma*dt);
for(int i = 1; i < N; i++){
double Z = dist(rng);
S.push_back(S[i-1] * drift * exp(vol*Z));
}
return S;
}
int main(){
const double r = 0.04; // Riskless interest rate
const double q = 0.0; // Divident yield
const double sigma = 0.20; // Volatility of stock
const double T = 1; // Time (expiry)
const int N = 1000; // Number of time steps
const double S0 = 100.0; // Initial stock price
const int M = 100; // Number of paths
for (int sindx = 0; sindx < M; sindx++)
{
std::vector<double> s = GBM(N,T,r,q,sigma,S0);
std::cout << "Simulation " << sindx << ": "
<< s[0] << ", " << s[1] << " ... " << s[N-2] << ", " << s[N-1]
<< std::endl;
}
return 0;
}
From the comments behind the constants, you want to simulate 10000 paths of an integration from 0 to 1 using 1000 subdivision steps, i.e., a step size of 0.001.
What you are doing is integrating one path over 10000 steps of step size 0.001, that is, from 0 to 10.
If you do this correctly, the result should look like a list of
S0 * exp( ((r-q)-0.5*sigma*sigma)*T + sigma*sqrt(T)*Z[i] )
as the value of the GBM at time T only depends on W(T) which is distributed as N(0,T) or sqrt(T)*N(0,1).

C++ Advice on manipulating output Matrix data

I have the following code.
Essentially it is creating N random normal variables, and running through an equation M times for a simulation.
The output should be an NxM matrix of data, however the only way I could do the calculation has the output as MxN. ie each M run should be a column, not a row.
I have attempted in vain to follow some of the other suggestions that have been posted on previous similar topics.
Code:
#include <iostream>
#include <time.h>
#include <random>
int main()
{
double T = 1; // End time period for simulation
int N = 4; // Number of time steps
int M = 2; // Number of simulations
double x0 = 1.00; // Starting x value
double mu = 0.00; // mu(x,t) value
double sig = 1.00; // sigma(x,t) value
double dt = T/N;
double sqrt_dt = sqrt(dt);
double** SDE_X = new double*[M]; // SDE Matrix setup
// Random Number generation setup
double RAND_N;
srand ((unsigned int) time(NULL)); // Generator loop reset
std::default_random_engine generator (rand());
std::normal_distribution<double> distribution (0.0,1.0); // Mean = 0.0, Variance = 1.0 ie Normal
for (int i = 0; i < M; i++)
{
SDE_X[i] = new double[N];
for (int j=0; j < N; j++)
{
RAND_N = distribution(generator);
SDE_X[i][0] = x0;
SDE_X[i][j+1] = SDE_X[i][j] + mu * dt + sig * RAND_N * sqrt_dt; // The SDE we wish to plot the path for
std::cout << SDE_X[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << " The simulation is complete!!" << std::endl;
std::cout << std::endl;
system("pause");
return 0;
}
Well why can't you just create the transpose of your SDE_X matrix then? Isn't that what you want to get?
Keep in mind, that presentation has nothing to do with implementation. Whether to access columns or rows is your decision. So you want an implementation of it transposed. Then quick and dirty create your matrix first, and then create your number series. Change i and j, and N and M.
I said quick and dirty, because the program at all is bad:
why don't you just keep it simple and use a better data structure for your matrix? If you know the size: compile-time array or dynamic vectors at runtime? Maybe there are some nicer implementation for 2d array.
There is a bug I think: you create N doubles and access index 0 to N inclusive.
In every iteration you set index 0 to x0 what is also needless.
I would change your code a bit make more clear:
create your matrix at first
initialize the first value of the matrix
provide an algorithm function calculating a target cell taking the matrix and the parameters.
Go through each cell and invoke your function for that cell
Thank you all for your input. I was able to implement my code and have it displayed as needed.
I added a second for loop to rearrange the matrix rows and columns.
Please feel free to let me know if you think there is anyway I can improve it.
#include <iostream>
#include <time.h>
#include <random>
#include <vector>
int main()
{
double T = 1; // End time period for simulation
int N = 3; // Number of time steps
int M = 2; // Number of simulations
int X = 100; // Max number of matrix columns
int Y = 100; // Max number of matrix rows
double x0 = 1.00; // Starting x value
double mu = 0.00; // mu(x,t) value
double sig = 1.00; // sigma(x,t) value
double dt = T/N;
double sqrt_dt = sqrt(dt);
std::vector<std::vector<double>> SDE_X((M*N), std::vector<double>((M*N))); // SDE Matrix setup
// Random Number generation setup
double RAND_N;
srand ((unsigned int) time(NULL)); // Generator loop reset
std::default_random_engine generator (rand());
std::normal_distribution<double> distribution (0.0,1.0); // Mean = 0.0, Variance = 1.0 ie Normal
for (int i = 0; i <= M; i++)
{
SDE_X[i][0] = x0;
for (int j=0; j <= N; j++)
{
RAND_N = distribution(generator);
SDE_X[i][j+1] = SDE_X[i][j] + mu * dt + sig * RAND_N * sqrt_dt; // The SDE we wish to plot the path for
}
}
for (int j = 0; j <= N; j++)
{
for (int i = 0; i <=M; i++)
{
std::cout << SDE_X[i][j] << ", ";
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << " The simulation is complete!!" << std::endl;
std::cout << std::endl;
system("pause");
return 0;
}

C++ doesn't show numbers with big decimals

I wrote a program of which the result made me wonder.
I have a double number with 3 decimals, but I need to change it to 2 decimals.
First I multiplied it with 100, then I changed it to an int, then I divided it by 100, but I don't know why
the result is wrong
input: 9.857
output is: 9.8499999999999996
Here is my code:
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
double sum = 9.857, temp = 0;
temp = int(sum * 100);
temp = int(temp);
sum = temp / 100;
printf("%.16f\n", sum);
}
input: 9.857
output is: 9.850000000000000
Second code:
#include <iostream>
#include <cstdio>
using namespace std;
int main(){
double sum = 9.857, temp = 0;
temp = int(sum * 100);
temp = int(temp);
sum = temp / 100;
printf("%.15f\n", sum);
}
Why are the answers of these two code snippets different?
In addition to floating point arithmetic, you are also using the unsafe printf-family of functions despite including <iostream>. The proper way to limit the precision of your output value in C++ is to set the ostream's precision value:
Example
#include <iostream>
int main()
{
double sum = 9.857, temp = 0;
std::cout.precision(4);
std::cout << "Value = " << sum << std::endl;
std::cout.precision(3);
std::cout << "Value = " << sum << std::endl;
std::cout.precision(2);
std::cout << "Value = " << sum << std::endl;
return 0;
}
If you wanted to do it in C, it would look like this:
Example
#include <stdio.h>
int main()
{
double sum = 9.857, temp = 0;
printf("Value = %.3f\n", sum);
printf("Value = %.2f\n", sum);
return 0;
}
If you are looking for exact values, floating point types are not the right type to use due to how they are stored (they will not be exact). This means that attempting to show 15-digits beyond the decimal is not likely to give you the same result as your input for many cases.