While I was writing a c++ program I stuck on a problem. In brief, my program input is one integer which is the number of coordinates that I have to input. And I have an algorithm that calculates the passed distance between all of the points. Here is my algorithm:
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
const double PI = 3.14;
const double rightXLimit = 5;
const double leftXLimit = -5;
const double topYLimit = 2;
const double bottomYLimit = -2;
const int ARR_SIZE = 100;
bool IsPointInRules(double x, double y)
{
if ((x >= leftXLimit && x <= rightXLimit) && (y >= bottomYLimit && y <= topYLimit))
{
return true;
}
return false;
}
double checkLimitsAndDistCalc(double x, double y, double x1, double y1)
{
if (!(IsPointInRules(x, y) || IsPointInRules(x1, y1)))
{
return 0;
}
else if (IsPointInRules(x, y) && (!IsPointInRules(x1, y1)))
{
if (x1 <= leftXLimit)
{
x1 = leftXLimit;
}
if (x1 >= rightXLimit)
{
x1 = rightXLimit;
}
if (y1 <= bottomYLimit)
{
y1 = bottomYLimit;
}
if (y1 >= topYLimit)
{
y1 = topYLimit;
}
}
else if ((!IsPointInRules(x, y)) && IsPointInRules(x1, y1))
{
if (x <= leftXLimit)
{
x = leftXLimit;
}
if (x >= rightXLimit)
{
x = rightXLimit;
}
if (y <= bottomYLimit)
{
y = bottomYLimit;
}
if (y >= topYLimit)
{
y = topYLimit;
}
}
double distance = sqrt(pow(x1 - x, 2) + pow(y1 - y, 2));
double result = ((PI * distance / 2) + distance) / 2;
//cout << setw(3) << x << setw(3) << y << setw(3) << x1 << setw(3) << y1 << " --> " << distance << " --> " << result << endl;
return result;
}
double calculateDistance(double* arrOne, double* arrTwo, int n)
{
double finalResult = 0;
for (int i = 0; i < n - 1; i++)
{
double getDistance = checkLimitsAndDistCalc(arrOne[i], arrTwo[i], arrOne[i + 1], arrTwo[i + 1]);
finalResult += getDistance;
}
return finalResult;
}
int main()
{
double coordsArrX[ARR_SIZE];
double coordsArrY[ARR_SIZE];
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> coordsArrX[i];
cin >> coordsArrY[i];
}
cout << setprecision(3) << fixed << calculateDistance(coordsArrX, coordsArrY, n) << '\n';
}
The problem is when I enter integers like coordinates the distance is wrong, but when enter double the distance is right and I can not find where is the problem. Here I tried some auto tests:
The problem is when I enter integers like coordinates the distance is wrong, but when enter double the distance is right and I can not find where is the problem.
That is an incorrect conclusion. The output is same whether you enter the coordinates using what appears to be integers or floating point numbers.
The output obtained using
7
0 0
0 3
-2 4
-1 1
-3 -1
4 1
6 3
is the same as using
7
0.0 0.0
0.0 3.0
-2.0 4.0
-1.0 1.0
-3.0 -1.0
4.0 1.0
6.0 3.0
See the output from using floating point input at http://ideone.com/fxgbga.
It appears that there is something else in your program that is not working as you are expecting.
Related
Here is the question:
There is a house with a backyard which is square bounded by
coordinates (0,0) in the southwest to (1000,1000) in
the northeast. In this yard there are a number of water sprinklers
placed to keep the lawn soaked in the middle of the summer. However,
it might or might not be possible to cross the yard without getting
soaked and without leaving the yard?
Input The input starts with a line containing an integer 1≤n≤1000, the
number of water sprinklers. A line follows for each sprinkler,
containing three integers: the (x,y)(x,y) location of the sprinkler
(0≤x,y,≤10000) and its range r (1≤r≤1000). The sprinklers will soak
anybody passing strictly within the range of the sprinkler (i.e.,
within distance strictly less than r).
The house is located on the west side (x=0) and a path is needed to
the east side of the yard (x=1000).
Output If you can find a path through the yard, output four real
numbers, separated by spaces, rounded to two digits after the decimal
place. These should be the coordinates at which you may enter and
leave the yard, respectively. If you can enter and leave at several
places, give the results with the highest y. If there is no way to get
through the yard without getting soaked, print a line containing
“IMPOSSIBLE”.
Sample Input
3
500 500 499
0 0 999
1000 1000 200
Sample output
0.00 1000.00 1000.00 800.00
Here is my thought process:
Define circle objects with x,y,r and write a function to determine if a given point is wet or not(inside the circle or not) on the circumference is not wet btw.
class circle {
int h;
int k;
int r;
public:
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
};
bool iswet(pair<int,int>* p){
if (pow(this->r - 0.001, 2) > (pow(p->first - this->h, 2) +
pow(p->second - this->k, 2) ) ) {
return true;
}
else
return false;
};
Then implement a depth first search, prioritizing to go up and right whenever possible.
However since circles are not guaranteed to be pass on integer coordinates an the result is expected in floats with double precision (xxx.xx). So if we keep everything in integers the grid suddenly becomes 100,000 x 100,000 which is way too big. Also the time limit is 1 sec.
So I thought ok lets stick to 1000x1000 and work with floats instead. Loop over int coordinates and whenever I hit a sprinkle just snap in the perimeter of the circle since we are safe in the perimeter. But in that case could not figure out how DFS work.
Here is the latest trial
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <utility>
#include <unordered_set>
#include <iomanip>
using namespace std;
const int MAXY = 1e3;
const int MAXX = 1e3;
const int MINY = 0;
const int MINX = 0;
struct pair_hash {
inline std::size_t operator()(const std::pair<int,int> & v) const {
return v.first*31+v.second;
}
};
class circle {
int h;
int k;
int r;
public:
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
};
bool iswet(pair<float,float>* p){
if (pow(this->r - 0.001, 2) > (pow(p->first - this->h, 2) + pow(p->second - this->k, 2) ) ) {
this->closest_pair(p);
return true;
}
else
return false;
};
void closest_pair(pair<float,float>* p){
float vx = p->first - this->h;
float vy = p->second - this->k;
float magv = sqrt(vx * vx + vy * vy);
p->first = this->h + vx / magv * this->r;
p->second = this->k + vy / magv * this->r;
}
};
static bool test_sprinkles(vector<circle> &sprinkles, pair<float,float>* p){
for (int k = 0; k < sprinkles.size(); k++)
if (sprinkles[k].iswet(p)) return false;
return true;
}
int main(){
int n; // number of sprinkles
while (cin >> n){
vector<circle> sprinkles_array;
sprinkles_array.reserve(n);
int h, k, r;
while (n--){
cin >> h >> k >> r;
sprinkles_array.push_back(circle(h, k, r));
}/* code */
pair<float,float> enter = make_pair(0, MAXY);
deque<pair<float,float>> mystack;
mystack.push_back(enter);
pair<float,float>* cp;
bool found = false;
unordered_set<pair<float, float>, pair_hash> visited;
while (!mystack.empty()){
cp = &mystack.back();
if (cp->first == MAXX) {
found = true;
break;
}
visited.insert(*cp);
if (cp->second > MAXY || cp->second < MINY || cp ->first < MINX ) {
visited.insert(*cp);
mystack.pop_back();
continue;
}
if (!test_sprinkles(sprinkles_array,cp)) {
continue;
}
pair<int,int> newpair = make_pair(cp->first, cp->second + 1);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first + 1 , cp->second);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first, cp->second - 1);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first - 1, cp->second);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
mystack.pop_back();
}
cout << setprecision(2);
cout << fixed;
if (found){
double xin = mystack.front().first;
double yin = mystack.front().second;
pair <float, float> p = mystack.back();
p.second++;
for (int k = 0; k < sprinkles_array.size(); k++)
if (sprinkles_array[k].iswet(&p)) break;
double xout = p.first;
double yout = p.second;
cout << xin << " " << yin << " " << xout << " " << yout << endl;
}
else
{
cout << "IMPOSSIBLE" << endl;
}
}
}
Yes #JosephIreland is right. Solved it with grouping intersecting (not touching) circles. Then these groups have maxy and min y coordinates. If it exceeds the yard miny and maxy the way is blocked.
Then these groups also have upper and lower intersection points with x=0 and x=1000 lines. If the upper points are larger than the yard maxy then the maximum entry/exit points are lower entery points.
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <utility>
#include <iomanip>
using namespace std;
const int MAXY = 1e3;
const int MAXX = 1e3;
const int MINY = 0;
const int MINX = 0;
struct circle {
int h;
int k;
int r;
float maxy;
float miny;
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
this->miny = this->k - r;
this->maxy = this->k + r;
};
};
struct group {
float maxy = -1;
float miny = -1;
vector<circle*> circles;
float upper_endy = -1;
float upper_starty = -1;
float lower_endy = -1;
float lower_starty = -1;
void add_circle(circle& c){
if ((c.maxy > this->maxy) || this->circles.empty() ) this->maxy = c.maxy;
if ((c.miny < this->miny) || this->circles.empty() ) this->miny = c.miny;
this->circles.push_back(&c);
// find where it crosses x=minx and x= maxx
float root = sqrt(pow(c.r, 2) - pow(MINX - c.h, 2));
float y1 = root + c.k;
float y2 = -root + c.k;
if (y1 > this->upper_starty) this->upper_starty = y1;
if (y2 > this->lower_starty) this->lower_starty = y2;
root = sqrt(pow(c.r, 2) - pow(MAXX - c.h, 2));
y1 = root + c.k;
y2 = -root + c.k;
if (y1 > this->upper_endy) this->upper_endy = y1;
if (y2 > this->lower_endy) this->lower_endy = y2;
};
bool does_intersect(circle& c1){
for(circle* c2 : circles){
float dist = sqrt(pow(c1.h - c2->h,2)) + sqrt(pow(c1.k - c2->k,2));
(dist < (c1.r + c2->r)) ? true : false;
};
};
};
int main(){
int n; // number of sprinkles
while (cin >> n){
vector<circle> sprinkles_array;
sprinkles_array.reserve(n);
int h, k, r;
while (n--){
cin >> h >> k >> r;
sprinkles_array.push_back(circle(h, k, r));
}/* code */
vector<group> groups;
group newgroup;
newgroup.add_circle(sprinkles_array[0]);
groups.push_back(newgroup);
for (int i = 1; i < sprinkles_array.size(); i++){
bool no_group = true;
for (group g:groups){
if (g.does_intersect(sprinkles_array[i])){
g.add_circle(sprinkles_array[i]);
no_group = false;
break;
}
}
if (no_group) {
group newgroup;
newgroup.add_circle(sprinkles_array[i]);
groups.push_back(newgroup);
}
}
float entery = MAXY;
float exity = MAXY;
bool found = true;
for (group g : groups){
if ((g.miny < MINY) && (g.maxy > MAXY)){
found = false;
break;
}
if (g.upper_starty > entery)
entery = g.lower_starty;
if (g.upper_endy > exity)
exity = g.lower_endy;
}
cout << setprecision(2);
cout << fixed;
if (found){
cout << float(MINX) << " " << entery << " " << float(MAXX) << " " << exity << endl;
}
else
{
cout << "IMPOSSIBLE" << endl;
}
}
}
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.
so, I got a code and I need to express my answers into 3 columns with x,y,a in program, by compiling I only get the calculation answers - 1 column with y value throughout the cycle [5] . How do I make it to a table with x, y, a columns and their values? Do I need another for cycle? Any suggestions are appreciated.
#include < iostream>
using namespace std;
float fy(float x, float a);
int main()
{
float a[5] = { -8, -6, -4, -2, 0 }
float y = 0;
int i = 0;
for (float x = -1; x <= 1; x += 0.5)
{
cout << fy(x, a[i]) << endl;
i++;
}
cin.get();
return 0;
}
float fy(float x, float a)
{
float y = 0;
if (sin(x)*a > 0)
y = sqrt(sin(x)*a);
else
cout << "no solution\n";
return y;
}
I guess what you want is something like this:
x y a
-1 2.59457 -8
-0.5 1.69604 -6
0 -nan -4
0.5 -nan -2
1 -nan 0
Right?
Following code should do the job:
#include <iostream>
#include <math.h>
using namespace std;
float fy(float x, float a);
int main() {
float a[5] = {-8, -6, -4, -2, 0};
float y = 0;
int i = 0;
cout << "x"
<< "\t"
<< "y"
<< "\t"
<< "a" << endl;
for (float x = -1; x <= 1; x += 0.5)
{
cout << x << "\t" << fy(x, a[i]) << "\t" << a[i] << endl;
i++;
}
cin.get();
return 0;
}
float fy(float x, float a) {
float y = 0;
if (sin(x) * a > 0)
y = sqrt(sin(x) * a);
else
y = sqrt(-1);
return y;
}
The problem in your code is that you only print the result of the function. So you neither print x nor you print the a[i] value. Check the replaced cout line and you'll see how to print the other values.
In my code, I'm trying to prevent circles from overlapping so I specified it as a condition on the distance between the centres of the circles but it seems to not work all the time
as you can see :
could it be some kind of numerical precision rounding problem ?
Here is the relevant code (I can post the whole code if needed):
const double win_size = 800;
const double L = 50e-9; //box size (m)
const double k = 1.38e-23; // Boltzmann constant = 1.38e-23 J/K
const double R = 1.6e-10*30; //N2 radius = 1.6e-10 m
const double m = 4.65e-26; //N2 mass = 4.65e-26 kg
struct parameters{
double x;
double y;
double v_x;
double v_y;
};
bool empty_space(double x, double y, struct parameters gas[], int N, int i){
if (i == 0) return true;
for (int i = 0; i<N; i++){
if (pow(x-gas[i].x,2) + pow(y-gas[i].y,2) <= 4*R*R){
cout << gas[i].x << " " << gas[i].y << endl;
return false;
}
}
return true;
}
void initialize(struct parameters gas[], int N, double T){ // Sets initial conditions (velocity depends on temperature)
int tries = 0;
double x, y;
for (int i=0; i<N; i++){
if (tries == 10000){
cout << "Couldn't fit " << N << " molecules in the box, aborting simulation... " << endl;
exit(1);
}
x = R + (L - 2*R)*rand()/RAND_MAX;
y = R + (L - 2*R)*rand()/RAND_MAX;
if (empty_space(x,y,gas,N,i)){
gas[i].x = x;
gas[i].y = y;
}
else {
i--;
tries++;
}
gas[i].v_x = sqrt(2*k*T/m)*(1-2.0*rand()/RAND_MAX);
gas[i].v_y = (2*(rand()%2) - 1)*sqrt(2*k*T/m - pow(gas[i].v_x, 2));
}
}
void draw(int window, struct parameters gas[], int N, int automatic){
g2_pen(window,g2_ink(window,0.8,0.3,0.4));
for (int i=0; i<N; i++){
g2_circle(window,gas[i].x*win_size/L,gas[i].y*win_size/L,R*win_size/L);
}
g2_flush(window);
usleep(10000);
g2_pen(window,0);
g2_filled_rectangle(window,0,0,win_size,win_size);
if (!automatic) getchar();
}
The first debugging step is to print the coordinates of the circles that have clashed somehow, then see what the "distance" function is returning for their centers. My guess it it's somehow a rounding problem but this seems to be what you need to do next.
Here is my code so far. There seems to be soemthing wrong since I keep getting an incorrect answer. I am writing in a text file that is formatted:
2
3.0 1.0
2 being the size of the array and then 3.0 and 1.0 being the coefficients. Hopefully I didnt miss much in my explanation. Any help would be greatly appreciated.
Thanks
double polyeval(double* polyarray, double x, int arraySize)
{
//int result = 0;
if(arraySize == 0)
{
return polyarray[arraySize];
}
//result += x*(polyarray[arraySize]+polyeval(polyarray,x,arraySize-1));
return polyarray[arraySize-1]+ (x* (polyeval(polyarray,x,arraySize-1)));
//return result;
}
int main ()
{
int arraySize;
double x;
double *polyarray;
ifstream input;
input.open("polynomial.txt");
input >> arraySize;
polyarray = new double [arraySize];
for (int a = arraySize - 1; a >= 0; a--)
{
input >> polyarray[a];
}
cout << "For what value x would you like to evaluate?" << endl;
cin >> x;
cout << "Polynomial Evaluation: " << polyeval(polyarray, x, arraySize);
delete [] polyarray;
}
the idea that if i read in a text file of that format varying in size that it will solve for any value x given by the user
Jut taking a wild guess
for (int a = arraySize - 1; a >= 0; a--)
// ^^
{
input >> polyarray[a];
}
One error is here:
for (int a = arraySize - 1; a > 0; a--)
{ //^^should be a >=0
input >> polyarray[a];
}
You are missing some entry this way.
The recursive function should look like the following:
int polyeval(double* polyarray, double x, int arraySize)
{
if(arraySize == 1)
{
return polyarray[arraySize-1];
}
return x*(polyarray[arraySize-1]+polyeval(polyarray,x,arraySize-1));
}
The problem is mainly with the definition of the polynomial coefficients.
Your code assumes a polynomial on the form:
x( p(n) + x( p(n-1) + x( p(n-2) + ... x(p(1) + p(0)))..))
This line:
result += x*(polyarray[arraySize]+polyeval(polyarray,x,arraySize-1));
Should become:
result += pow(x,arraySize)*polyarray[arraySize]+polyeval(polyarray,x,arraySize-1);
This way the polynomial is defined correctly as p(n)x^n + p(n-1)x^(n-1) ... + p1 x + p0
Couldn't work out exactly what you were trying to do, or why you were using recursion. So I whipped up a non-recursive version that seems to give the right results.
#include <iostream>
using namespace std;
double polyeval(const double* polyarray, double x, int arraySize) {
if(arraySize <= 0) { return 0; }
double value = 0;
const double * p = polyarray + (arraySize-1);
for(int i=0; i<arraySize; ++i) {
value *= x;
value += *p;
p--;
}
return value;
}
int main () {
const int arraySize = 3;
const double polyarrayA[3] = {0.0,0.0,1.0}; // 0 + 0 x + 1 x^2
const double polyarrayB[3] = {0.0,1.0,0.0}; // 0 + 1 x + 0 x^2
const double polyarrayC[3] = {1.0,0.0,0.0}; // 1 + 0 x + 0 x^2
cout << "Polynomial Evaluation A f(x) = " << polyeval(polyarrayA, 0.5, arraySize)<<std::endl;
cout << "Polynomial Evaluation B f(x) = " << polyeval(polyarrayB, 0.5, arraySize)<<std::endl;
cout << "Polynomial Evaluation C f(x) = " << polyeval(polyarrayC, 0.5, arraySize)<<std::endl;
}
You can see it running here:
http://ideone.com/HE4r6x