I am writing a harmonic oscillator program , but it does an exponential decay instead and I am not sure why. I have the code below. I use F= -k x and F = m a
I assume m = 1 and k = 1, so a = -x
So my equations to find velocity and position are
v(t) = v(t-dt) - x(t-dt) * dt
x(t) = x(t-dt) + v(t-dt) * dt
I am not sure what I am doing wrong
The code associated with this is
#include <iostream>
#include <fstream>
using namespace std;
double updateX(double intialV, double intialX, double step);
double updateV(double intialV, double intialX, double step);
int main()
{
long double position[2];long double velocity[2];
position[0] = 0.0; velocity[0] = 1.0; double time = 0.0; double step = .1;
ofstream outputFile;
outputFile.open("velo1.dat");
outputFile << time << " " << position[0] << " " << velocity[0] << "\n";
for(int i = 1; i < 50; i++)
{
time = i * step;
velocity[1] = updateV(velocity[0], position[0], step);
position[1] = updateX(velocity[0], position[0], step);
outputFile << time << " " << position[1] << " " << velocity[1] << "\n";
velocity[0] = velocity[1];
position[0] = velocity[1];
}
return 0;
outputFile.close();
}
double updateX(double intialV, double intialX, double step)
{
double stuff =(intialX + intialV * step);
return stuff;
}
double updateV(double intialV, double intialX, double step)
{
double stuff = (intialV - intialX * step) ;
return stuff;
}
Related
I'm trying to implement logistic regression in C++, but the predictions I'm getting are not even close to what I am expecting. I'm not sure if there is an error in my understanding of logistic regression or the code.
I have reviewed the algorithms and messed with the learning rate, but the results are very inconsistent.
double theta[4] = {0,0,0,0};
double x[2][3] = {
{1,1,1},
{9,9,9},
};
double y[2] = {0,1};
//prediction data
double test_x[1][3] = {
{9,9,9},
};
int test_m = sizeof(test_x) / sizeof(test_x[0]);
int m = sizeof(x) / sizeof(x[0]);
int n = sizeof(theta) / sizeof(theta[0]);
int xn = n - 1;
struct Logistic
{
double sigmoid(double total)
{
double e = 2.71828;
double sigmoid_x = 1 / (1 + pow(e, -total));
return sigmoid_x;
}
double h(int x_row)
{
double total = theta[0] * 1;
for(int c1 = 0; c1 < xn; ++c1)
{
total += theta[c1 + 1] * x[x_row][c1];
}
double final_total = sigmoid(total);
//cout << "final total: " << final_total;
return final_total;
}
double cost()
{
double hyp;
double temp_y;
double error;
for(int c1 = 0; c1 < m; ++c1)
{
//passes row of x to h to calculate sigmoid(xi * thetai)
hyp = h(c1);
temp_y = y[c1];
error += temp_y * log(hyp) + (1 - temp_y) * log(1 - hyp);
}// 1 / m
double final_error = -.5 * error;
return final_error;
}
void gradient_descent()
{
double alpha = .01;
for(int c1 = 0; c1 < n; ++c1)
{
double error = cost();
cout << "final error: " << error << "\n";
theta[c1] = theta[c1] - alpha * error;
cout << "theta: " << c1 << " " << theta[c1] << "\n";
}
}
void train()
{
for(int epoch = 0; epoch <= 10; ++epoch)
{
gradient_descent();
cout << "epoch: " << epoch << "\n";
}
}
vector<double> predict()
{
double temp_total;
double total;
vector<double> final_total;
//hypothesis equivalent function
temp_total = theta[0] * 1;
for(int c1 = 0; c1 < test_m; ++c1)
{
for(int c2 = 0; c2 < xn; ++c2)
{
temp_total += theta[c2 + 1] * test_x[c1][c2];
}
total = sigmoid(temp_total);
//cout << "final total: " << final_total;
final_total.push_back(total);
}
return final_total;
}
};
int main()
{
Logistic test;
test.train();
vector<double> prediction = test.predict();
for(int c1 = 0; c1 < test_m; ++c1)
{
cout << "prediction: " << prediction[c1] << "\n";
}
}
start with a very small learning rate wither larger iteration number at try. Haven`t tested ur code. But I guess the cost/error/energy jumps from hump to hump.
Somewhat unrelated to your question, but rather than computing e^-total using pow, use exp instead (it's a hell of a lot faster!). Also there is no need to make the sigmoid function a member func, make it static or just a normal C func (it doesn't require any member variable from your struct).
static double sigmoid(double total)
{
return 1.0 / (1.0 + exp(-total));
}
I am used to write C++ project in CodeBlocks, but for some stupid reasons I have to show it to my teacher in VisualStudio. I tried to make a console app or an empty project, and copied my main file there, but with the first one I get bunch of erorrs and the second one I get 'The system cannot find the way specified'. What is different in VisualStudio? I don't understand at all what is wrong.
here is my code
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
const int kroku = 1000;
const double aa = 0; //pocatecni bod intervalu
const double bb = 1; //konečný bod intervalu
double a; //parametr
const double h = (bb - aa) / kroku; //krok
double p(double t) { //(py')' - qy = f
return exp(a*pow(t, 2));
}
double q(double t) {
return -exp(a*pow(t, 2))*pow(a, 2)*pow(t, 2);
}
double dp(double t) {
return 2 * t*a*exp(a*pow(t, 2));
}
double y[kroku + 1]; //řešení původní rce
double dydx[kroku + 1];
double z[kroku + 1]; //řešení dílčí rce
double dzdx[kroku + 1];
double x[kroku + 1]; //rozdělení intervalu (aa, bb) po krocích h
void generateX() { //generuje hodnoty x
for (int k = 0; k <= kroku; k++) {
x[k] = aa + k*h;
}
}
double partial(double pp1, double pp2, double w[kroku + 1], double dwdx[kroku + 1], double v)//řešení rce (pw')' - qw = g s pp
{
w[v] = pp1; //inicializace - počáteční podmínka
dwdx[v] = pp2; //inicialzace - počáteční podmínka
for (int i = 0; i <= kroku; i++) { //substituce dwdx proměnná -> dwdx = (w_(n+1) - w_n)/h) && dwdx =
w[i + 1] = h*dwdx[i] + w[i];
dwdx[i + 1] = (h / p(aa + h*i))*(q(aa + h*i)*w[i] - dp(aa + h*i)*dwdx[i]) + dwdx[i];
}
return 0;
}
double omega1, omega2; //nové počáteční podmínky omega1 = y(x0), omega2 = y'(x0)
void print(double N[kroku + 1])
{
fstream file;
file.open("data.dat", ios::out | ios::in | ios::trunc);//otevření/vytvoření(trunc) souboru
if (file.is_open()) //zápis do souboru
{
cout << "Writing";
file << "#" << "X" << " " << "Y" << endl;
for (int j = 0; j <= kroku; j++) {
file << x[j] << " " << N[j] << endl;
}
file << "#end";
}
else
{
cout << "Somethinq went wrong!";
}
file.close();
}
int main()
{
double alpha; //pocatecni podminka y(aa) = alpha
double beta; //y(bb) = beta
cout << "Assign the value of beta " << endl;
cin >> beta;
cout << "Assign the value of alpha " << endl;
cin >> alpha;
cout << "Assign the value of parameter a" << endl;
cin >> a;
double alpha1 = 0; //alpha1*p(aa)*y'(aa) - beta1*y(aa) = gamma1
//double alpha2 = 0; //alpha2*p(bb)*y'(bb) + beta2*y(bb) = gamma2
double beta1 = -1;
double beta2 = 1;
double gamma1 = alpha;
double gamma2 = beta;
generateX();
partial(alpha1, beta1 / p(aa), z, dzdx, aa); //(pz')'-qz = 0
omega1 = gamma2 / beta2;
omega2 = 1 / (z[kroku] * p(bb))*(gamma1 + dzdx[kroku] * p(bb));
partial(omega1, omega2, y, dydx, aa);//(py')' - qy = f = 0
print(y);
return 0;
strong text}
when I add
#include "stdafx.h"
I get four errors
2x 'Expression must have integral or unscoped enum type'
2x 'subscript is not of integral type'
for these lines
w[v] = pp1;
dwdx[v] = pp2;
Could anyone please help me? Thank you a lot
array subscript v in your line
w[v]
can not be double. It must be of interger type.
I am trying to calculate distances between particles in a box. If the distance calculated is greater than a preset cut-off distance, then the potential energy is 0. Otherwise, it is 1.
There are some rounding issues I think and I am not familiar with variable types and passing variables through functions to know what to do next.
The error
When I calculate d0 by hand I get d0 = 0.070 - this is not what the computer gets! The computer gets a number on the order of e-310.
All of the calculated distances (dij) are no shorter than 1/14, which is much larger than e-310. According to my if statement, if dij>d0, then U=0, so I should get a total energy of 0, but this is what I get:
d0 is 6.95322e-310
i is 0 j is 1 dij is 0.0714286 d0 is 6.95322e-310 Uij is 1
.....
Energy of the system is 24976
Please let me know if I could provide any more information. I did not include the entirety of my code, but the other portion involves no manipulation of d0.
I copied the relevant pieces of code below
Part 1: relevant box data
class Vector {
public:
double x;
double y;
Vector() {
}
Vector (double x_, double y_) {
x = x_;
y = y_;
}
double len() {
return sqrt(x*x + y*y);
}
double lenSqr() {
return x*x + y*y;
}
};
class Atom
{
public:
Vector pos;
Vector vel;
Vector force;
Atom (double x_, double y_) {
pos = Vector(x_, y_);
}
};
class BoxData
{
public:
const double Len = 1.;
const double LenHalf = 0.5 * Len;
long double d = 1. / 14; // d is the distance between each atom
in the initial trigonal lattice
int nu = 7; // auxillary parameter - will be varied
long double d0 = d * (1 - 2^(nu - 8)); // cutoff distance
double alpha = d - d0; // maximum allowed displacement
};
int main() {
// Initialize box
LoadBox();
// Institute a for loop here
SystemEnergy();
MonteCarloMove();
return 0;
}
//Putting atoms into box
void LoadBox()
{
ofstream myfile("init.dat", ios::out);
//Load atoms in box in triangular offset lattice
const double x_shift = 1. / 14;
const double y_shift = 1. / 16;
double x = 0;
double y = 0;
double x_offset = 0;
for (y = 0; y <= 1. - y_shift; y += y_shift) {
for (x = x_offset; x < 0.99; x += x_shift) {
// create atom in position (x, y)
// and store it in array of atoms
atoms.push_back(Atom(x, y));
}
// every new row flip offset 0 -> 1/28 -> 0 -> 1/28...
if (x_offset < x_shift / 4) {
x_offset = x_shift / 2;
} else {
x_offset = 0.0;
}
}
const int numAtoms = atoms.size();
//print the position of each atom in the file init.dat
for (int i = 0; i < numAtoms; i++) {
myfile << "x is " << atoms[i].pos.x << " y is " << atoms[i].pos.y << endl;
}
myfile.close();
}
Part 2 : Energy calculation
vector<Atom> atoms;
BoxData box_;
void SystemEnergy()
{
ofstream myfile("energy.dat", ios::out);
double box_Len, box_LenHalf, box_d0;
double dij; // distance between two atoms
double Uij; // energy between two particles
double UTotal = 0;
double pbcx, pbcy; // pbc -> periodic boundary condition
double dx, dy;
myfile << "d0 is " << box_d0 << endl;
// define the number of atoms as the size of the array of atoms
const int numAtoms = atoms.size();
//pick atoms
for (int i=0; i<numAtoms-1; i++) { // pick one atom -> "Atom a"
Atom &a = atoms[i];
for (int j=i+1; j<numAtoms; j++) { // pick another atom -> "Atom b"
Atom &b = atoms[j];
dx = a.pos.x - b.pos.x;
dy = a.pos.y - b.pos.y;
pbcx = 0.0;
pbcy = 0.0;
// enforce periodic boundary conditions
if(dx > box_LenHalf) pbcx =- box_Len;
if(dx < -box_LenHalf) pbcx =+ box_Len;
if(dy > box_LenHalf) pbcy =- box_Len;
if(dy < -box_LenHalf) pbcy =+ box_Len;
dx += pbcx;
dy += pbcy;
// calculate distance between atoms
dij = sqrt(dx*dx + dy*dy);
// compare dij to the cutoff distance to determine energy
if (dij > box_d0) {
Uij = 0;
} else {
Uij = 1;
}
myfile << "i is " << i << " j is " << j << " dij is " << dij << " d0 is " << box_d0 << " Uij is " << Uij << endl;
UTotal += Uij; // sum the energies
}
}
myfile << "Energy of the system is " << UTotal << endl;
myfile.close();
}
Sorry for the formatting issues - getting the hang of copy/pasting to the forum.
I am writing a Pi estimator for class. The point is to estimate Pi using OpenMP and to analyze the speedup provided by using three separate schedules, static, dynamic and guided. However my total time skyrockets when I add threads. My total time for 1 thread is around 21 seconds, and for 2 threads is roughly 145 seconds. I can't figure out why. Here is my code:
#include <stdio.h>
#include <time.h>
#include <ctime>
#include <omp.h>
#include <assert.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;
void computePi(int, int);
int main(int argc, char *argv[])
{
cout.precision(20);
omp_set_dynamic(0);
int i, p;
int n;
// loop {number of iterations} [number of threads]
if (argc > 1)
{
n = atoll(argv[1]);
p = atoi(argv[2]);
}
else
{
n = 10000000;
p = 8;
}
printf("Debug: dart throws = %d \n", n);
printf("Debug: number of requested threads = %d\n", p);
omp_set_num_threads(p);
double time = omp_get_wtime();
//dispArray(a,n);
computePi(n, p);
time = omp_get_wtime() - time;
printf("Total time = %f seconds \n ", time);
return 0;
}
void computePi(int n, int p) {
omp_set_num_threads(p);
int i;
int hits = 0;
srand(time(NULL));
double timeStatic = omp_get_wtime();
#pragma omp parallel for shared(i) schedule(static) reduction(+:hits)
for (i = 0; i<n; i++)
{
float r, x, xdiff, y, ydiff;
x = (float)rand() / (float)RAND_MAX;
y = (float)rand() / (float)RAND_MAX;
if (y > .50)
{
ydiff = y - .50;
}
else
{
ydiff = .50 - y;
}
if (x > .50)
{
xdiff = x - .50;
}
else
{
xdiff = .50 - x;
}
xdiff *= xdiff;
ydiff *= ydiff;
r = sqrt(ydiff + xdiff);
if (r <= .50)
{
hits += 1;
}
}
timeStatic = omp_get_wtime() - timeStatic;
float percentage;
percentage = (float)hits / (float)n;
cout << "Static Loop" << endl;
cout << "Hit Percentage: " << percentage * 100 << "%" << endl;
cout << "Pi Estimation: " << percentage * 4 << endl;
cout << "Time Taken: " << timeStatic << endl << endl;
hits = 0;
double timeDynamic = omp_get_wtime();
#pragma omp parallel for shared(i) schedule(dynamic) reduction(+:hits)
for (i = 0; i<n; i++)
{
float r, x, xdiff, y, ydiff;
x = (float)rand() / (float)RAND_MAX;
y = (float)rand() / (float)RAND_MAX;
if (y > .50)
{
ydiff = y - .50;
}
else
{
ydiff = .50 - y;
}
if (x > .50)
{
xdiff = x - .50;
}
else
{
xdiff = .50 - x;
}
xdiff *= xdiff;
ydiff *= ydiff;
r = sqrt(ydiff + xdiff);
if (r <= .50)
{
hits += 1;
}
}
timeDynamic = omp_get_wtime() - timeDynamic;
percentage = (float)hits / (float)n;
cout << "Dynamic Loop" << endl;
cout << "Hit Percentage: " << percentage * 100 << "%" << endl;
cout << "Pi Estimation: " << percentage * 4 << endl;
cout << "Time Taken: " << timeDynamic << endl << endl;
hits = 0;
double timeGuided = omp_get_wtime();
#pragma omp parallel for shared(i) schedule(guided) reduction(+:hits)
for (i = 0; i<n; i++)
{
float r, x, xdiff, y, ydiff;
x = (float)rand() / (float)RAND_MAX;
y = (float)rand() / (float)RAND_MAX;
if (y > .50)
{
ydiff = y - .50;
}
else
{
ydiff = .50 - y;
}
if (x > .50)
{
xdiff = x - .50;
}
else
{
xdiff = .50 - x;
}
xdiff *= xdiff;
ydiff *= ydiff;
r = sqrt(ydiff + xdiff);
if (r <= .50)
{
hits += 1;
}
}
timeGuided = omp_get_wtime() - timeGuided;
percentage = (float)hits / (float)n;
cout << "Guided Loop" << endl;
cout << "Hit Percentage: " << percentage * 100 << "%" << endl;
cout << "Pi Estimation: " << percentage * 4 << endl;
cout << "Time Taken: " << timeGuided << endl << endl;
return;
}
Any help would be appreciated.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
The error is with:
estimate1 = leibnizPi (nTerms, estimatedV1);
&
estimate2 = wallisPi (nTerms, estimatedValue2);
I'm thinking it has to do with the way it is set up to reference the estimatedValue in the function, or the way it is being called is incorrect.
Any help is much appreciated!
NOTE: HAS TO REMAIN VOID. Sorry about that.
#include <iostream>
#include <cmath>
//
// This program will be used in the second assignment (functions)
//
using namespace std;
const double PI = 3.14159265358979323846;
void leibnizPi (int numberofterms, double &estimatedValue1 )
{
double sign = 1.0;
double sum = 0.0;
for (int i = 0; i < numberofterms; ++i) {
double denominator = 2.0 * i + 1.0;
double term = 4.0 / denominator;
sum = sum + sign * term;
sign = -sign;
}
estimatedValue1 = sum;
}
void wallisPi (int numberofterms, double &estimatedValue2)
{
double product = 1.0;
for (int i = 1; i < numberofterms; ++i) {
double r = 2.0*i;
r = r*r;
double term = r/(r-1.0);
product = product * term;
}
estimatedValue2 = 2.0 * product;
}
double abstractError (double computedValue);
double relativeError (double computedValue);
int main (int argc, char** argv) {
double estimate1 = 0;
double absErr1 = 0;
double relErr1 = 0;
double estimate2 = 0;
double absErr2 = 0;
double relErr2 = 0;
double estimatedV1 = 0;
double estimatedValue2 = 0;
for (int nTerms = 1; nTerms < 100001; nTerms = nTerms * 4) {
// Estimate Pi by two different methods
// Leibniz' sum
estimate1 = leibnizPi (nTerms, estimatedV1);
absErr1 = abstractError (estimate1);
relErr1 = relativeError (estimate1);
// Wallis' product
estimate2 = wallisPi (nTerms, estimatedValue2);
absErr2 = abstractError (estimate2);
relErr2 = relativeError (estimate2);
cout << "After " << nTerms << " terms\n";
cout << "Leibniz' estimate: "<< estimate1 << "\n";
cout << "Absolute error: " << absErr1
<< "\tRelative error: " << relErr1
<< "\n";
cout << "Wallis' estimate: "<< estimate2 << "\n";
cout << "Absolute error: " << absErr2
<< "\tRelative error: " << relErr2
<< "\n";
cout << endl;
}
return 0;
}
double abstractFunction (double computedValue)
{
double abstractError = abs(computedValue - PI);
return abstractError;
}
double relativeFunction (double computedValue){
double relativeError1 = abs(computedValue - PI) / PI;
return relativeError1;
}
You cannot use the return value of a function returning void, because there isn't one. Instead, you may want to try something like this:
double leibnizPi (int numberofterms, double &estimatedValue1 )
{
double sign = 1.0;
double sum = 0.0;
for (int i = 0; i < numberofterms; ++i) {
double denominator = 2.0 * i + 1.0;
double term = 4.0 / denominator;
sum = sum + sign * term;
sign = -sign;
}
estimatedValue1 = sum;
return estimatedValue1;
}
double wallisPi (int numberofterms, double &estimatedValue2)
{
double product = 1.0;
for (int i = 1; i < numberofterms; ++i) {
double r = 2.0*i;
r = r*r;
double term = r/(r-1.0);
product = product * term;
}
estimatedValue2 = 2.0 * product;
return estimatedValue2;
}
If you must use a void function, you should assign the variable passed as a parameter (estimatedV1) to the secondary variable (estimate1). Like so:
leibnizPi (nTerms, estimatedV1);
estimate1 = estimatedV1;
No, the problem is that you haven't defined your functions to return anything, and than you try to take what they return (which is undefined) and assign it to a variable, which is a mistake.
Define it as such double leibnizPi (int numberofterms, double &estimatedValue1 )
And add a return statement.
If you can't change the return type of the function, than don't try to treat it as returning a value. Just write leibnizPi (nTerms, estimatedV1); instead of estimate1 = leibnizPi (nTerms, estimatedV1);