Need to create function to optimise and make more efficient - c++

I've written this code that writes coordinates to a text file. I then use excel to plot these coordinates and it creates a rectangle with circles in it.
It works completing fine, but I want to optimize it. I thought I could optimize it by creating another function that has the syntax for the coordinates so I can call the function rather than writing it out every time and repeating the code. However, I am not sure how to do this, I have tried but its not working so some help would be really appreciated.
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
#define PI 3.14159265
//this is the function i am trying to create
double coordinate_syntax(double x_coordinate, double y_coordinate){
return map << x_coordinate << ' ' << y_coordinate << endl;
}
int build_environment_map(){
double x0[5]={0.8, 0.8, 1.7, 2.2, 2.25};
double y0[5]={1.5, 2.25, 1.0, 1.3, 0.25};
double r=0.125, wallLength=2.5;
double RD=PI /180;
ofstream map;
map.open("EnvironmentMap.txt");
// The following code is to create a charger based on its centre.
for (int i=0; i<360; i=i+20) {
map << x0[4] + r*cos(i*RD) << ' ' << y0[4] + r*sin(i*RD) << endl;
//coordinate_syntax( x0[4] + r*cos(i*RD), y0[4] + r*sin(i*RD) );
}
for (int i=0; i<360; i=i+10) {
map << x0[0] + r*cos(i*RD) << ' ' << y0[0] + r*sin(i*RD) << endl;
//coordinate_syntax(x0[0]+ r*cos(i*RD), y0[0]+ r*sin(i*RD));
}
for (double j=0 ; j<wallLength; j=j+0.01){
map << j << ' ' << 0 << endl;
//coordinate_syntax(j,0);
}
for (double x=0.3; x<0.55; x=x+0.01){
map << x << ' ' << 0.3 << endl;
//coordinate_syntax(x, 0.3);
}
map.close();
return 0;
}
int main(int argc, char **argv){
int i;
//calling the function
i = build_environment_map();
return 0;
}

Related

How to create objects inside a loop which name depends on an int

I have an structure named "Particle" and I want to create several objects whose names depends on an int.
As I am inside a for loop the name is going to change as follows: part0, part1, part2.
for (int i = 0; i<num_particles; i++)
{
//double sample_x, sample_y, sample_theta;
string name = "part" + std::to_string(i);
Particle name;
name.id = i;
name.x = dist_x(gen);
name.y = dist_y(gen);
name.theta = dist_theta(gen);
cout << "Sample" << " " << name.x << " " << name.y << " " << name.theta << endl;
}
As you can imagine this approach doesn't work, do you have any solution?
I have updated my question, now this is my new approach:
I have created a vector and an int "number of particles":
std::vector<Particle> particles;
And the function code:
void ParticleFilter::init(double x, double y, double theta, double std[]) {
// TODO: Set the number of particles. Initialize all particles to first position (based on estimates of
// x, y, theta and their uncertainties from GPS) and all weights to 1.
// Add random Gaussian noise to each particle.
// NOTE: Consult particle_filter.h for more information about this method (and others in this file).
default_random_engine gen;
normal_distribution<double> dist_x(x, std[0]);
normal_distribution<double> dist_y(y, std[1]);
normal_distribution<double> dist_theta(theta, std[2]);
//for (int i = 0; i<num_particles; i++)
//{
//double sample_x, sample_y, sample_theta;
//string name = "part";
//+ std::to_string(i);
//Particle particles;
particles[num_particles].id =num_particles;
particles[num_particles].x = dist_x(gen);
particles[num_particles].y = dist_y(gen);
particles[num_particles].theta = dist_theta(gen);
num_particles++;
cout << "Sample" << " " << particles[num_particles].x << " " << particles[num_particles].y << " " << particles[num_particles].theta << endl;
//}
}
But it doesn't work yet, it outputs "Segmentation fault".
you can use itoa() function of cstdlib simply in your code.
for (int i = 0; i<10; i++)
{
char a[max];
string pa="part_";
string name = pa + itoa(i,a,i+1) ;
cout << "Sample" << " " << name << endl;
}
}
Sample Output:
Sample part_0
Sample part_1
Sample part_2
Sample part_3
Sample part_4
Sample part_5
Sample part_6
Sample part_7
Sample part_8
Sample part_9
This construct exists in C++, it is called std::vector.
// we want to have a bunch of variables of type Particle
// all named particles[i] for i == 0,1,2....
std::vector<Particle> particles;
// create a new particle variable
particles.emplace_back(x, y, theta);
// print the variable number 42
std::cout << particles[42];
Why do you want to down the messy road of variable naming such as var0, var1, var2 and so on? I'd recommend creating an array or vector.
It's not clear from your code snippet that why you need to create variables with different names. Moreover, your code/usecase doesn't sit right with the concept of variable scoping.

print a filled square in console

I need to print a filled square in Linux terminal using my C++ program (1cm x 1cm size). I tried to use ASCII 254 (■), but in terminal it print as garbage character. I'm not sure how to print extended ASCII character using c++. Here are two methods I have tried to print extended ASCII. but not succeed.
First method
for(int i=128; i< 255; i++ )
{
std::cout << static_cast<char>(i) << std::endl;
}
Second method
unsigned char temp = 'A'
for(int i=65; i< 255; i++ )
{
std::cout << temp++ << std::endl;
std::wcout << temp << std::endl;
}
Any suggestion or alternative Idea?
Try using the unicode cout << "\u25A0";
http://www.fileformat.info/info/unicode/category/So/list.htm
Or try just:
std::cout << (char)254u;
To get output as you want, try this:
#include<iostream>
#include<windows.h>
using namespace std;
void setconsolecolor(int textColor, int bgColor)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (textColor +
(bgColor * 16)));
}
int main()
{
cout<<"The chunk of Blocks in the colors : \n";
cout<<" ";
setconsolecolor(0,9);
cout<<" ";
setconsolecolor(0,4);
cout<<" ";
setconsolecolor(0,8);
cout<<" \n";
setconsolecolor(0,0);
return 0;
}
Try this :
char t = -2;
cout << t;
Like Sebastian Kuczyński has suggested , we could use that to do great stuff like bar graphs , hostogram etc. Its very cool.
Code
printf("\n\nHistogram of Float data\n");
for (i = 1; i <= bins; i++)
{
count = hist[i];
printf("0.%d |", i - 1);
for (j = 0; j < count; j++)
{
printf("%c", (char)254u);
}
printf("\n");
}
Output
Histogram of Float data
0.0 |■■■■■■■■■■■■■■■■■■■■■■
0.1 |■■■■■■■■■■■■■■■■
0.2 |■■■■■
0.3 |■■■■■■■■■■■■■■
0.4 |■■■■■■■■
0.5 |■■■■■■■■■■■■■■■■
0.6 |■■■■■■■■■■
0.7 |■■■■■■■
0.8 |■■■■■■■■■■■■■■■
0.9 |■■■■■■■

How do we use a float and double variable to calculate and print an operation in C++?

To clarify, this is a lab for class. I'm just learning all the fundamentals right now. I am trying to figure out how to print the total using a float variable AND a double variable (I thought we can just choose one or the other) while using loop mechanisms (while, do-while or for). I decided to go with the for loop. Any suggestions would be helpful. What I have now prints every single fraction until it gets to the very last one. I tried different variations but so far I got nothing.
I need help calculating the total for:
1/1 + 1/2 + 1/3 + 1/4 +....... 1/99999999 + 1/100000000
This is what I have so far:
#include <iostream>
using namespace std;
int main()
{
float answer = 0;
int num;
for (int den = 1; den <= 100000000; ++den)
{
num = 1;
cout << num << "/" << den;
if (den == 100000000)
cout << " = " << endl;
else
cout << " + ";
answer += ( (float)num ) / ( (float)den );
}
cout << answer << endl;
}
Thanks!
At any point in time, your program has to be using either a float or a double, so I guess you're wanting to reuse your calculation code for each of those types in turn. Here's an example of how to do the calculation twice using a template - first for float, then for double:
#include <iostream>
template <typename T>
void calculate()
{
T answer = 0;
for (int den = 1; den <= 100000000; ++den)
answer += T(1) / T(den);
std::cout << answer << '\n';
}
int main()
{
calculate<float>();
calculate<double>();
}

Point inside or in boundary of polygon

I'm using the algorithm in http://www.ecse.rpi.edu/~wrf/Research/Short_Notes/pnpoly.html,
but when the input point is in boundary, that algorithm gives wrong for me. Can anyone help me with point in boundary case?
Any help is appreciated.
This is the main function
#include <iostream>
#include <Polygon.h>
using namespace std;
int main()
{
vector<Point> v;
//v.push_back(make_pair(3.0,3.0));
v.push_back(make_pair(1.0,1.0));
v.push_back(make_pair(1.0,5.0));
v.push_back(make_pair(5.0,5.0));
v.push_back(make_pair(5.0,1.0));
Polygon *p = new Polygon(v);
cout << "A: " << p->IsInside(make_pair(1.0,3.0)) << endl;
cout << "B: " << p->IsInside(make_pair(3.0,1.0)) << endl;
cout << "C: " << p->IsInside(make_pair(5.0,3.0)) << endl;
cout << "D: " << p->IsInside(make_pair(3.0,5.0)) << endl;
delete p;
return 0;
}
This is the checking function
bool Polygon::IsInside(Point p)
{
/*determine whether a point is inside a polygon or not
* polygon's vertices need to be sorted counterclockwise
* source :
* http://www.ecse.rpi.edu/~wrf/Research/Short_Notes/pnpoly.html
*/
bool ans = false;
for(size_t c=0,d=this->vertices.size()-1; c<this->vertices.size(); d=c++)
{
if( ((this->vertices[c].y > p.y) != (this->vertices[d].y > p.y)) &&
(p.x < (this->vertices[d].x - this->vertices[c].x) * (p.y - this->vertices[c].y) /
(this->vertices[d].y - this->vertices[c].y) + this->vertices[c].x) )
ans = !ans;
}
return ans;
}
From the website documentation:
"PNPOLY partitions the plane into points inside the polygon and points outside the polygon. Points that are on the boundary are classified as either inside or outside. ..."
Please read the documentation available on the site again.It answers your question.
In the end, you will probably have to to live with the ambiguity of floating point calculations.

segmentation fault that goes away by using iostream

So this is gnarly. I have a piece of code that used the Columbia Physics System c++ library. I get a segfault when I run it, most probably because the classes: CgArg, and vector f_field_in, etc are uninitialised. I used Valgrind and found that indeed the various arguments were pointing to invalid memory.
The strange this is that if I insert an iostream call anywhere in the two functions, the segfault goes away. I found out when I put flags in places to debug. It also doesn't segfault if I define an integer and write a simple cin >>. That's why I think it's something to do with iostream.
If you know of any reason why a call to iostream would somehow give pieces of code to the arguments, I'd be very thankful if you shared it with me.
#include <iostream>
using namespace std;
#include <config.h>
#include <util/lattice.h>
#include <util/dirac_op.h>
#include <util/gjp.h>
#include <interface.h>
#define CLOVER_MAT_SIZE 72
USING_NAMESPACE_CPS
// Same function for clover matrix and its inverse.
static
void interface(double *h_quda_clover, double *h_cps_clover)
{
h_quda_clover[0]=h_cps_clover[0]; // c00_00_re = C0.x, A0
...and lots more of this stuff...
h_quda_clover[35+36]=h_cps_clover[34+36]; // c32_31_im = C8.w, A5
}
static
void fill_h_clover_inv(Lattice &lat, int site[], double *h_quda_clover_inv_site)
{
double h_cps_clover_inv[72];
Vector *f_field_out, *f_field_in;
CgArg *arg;
CnvFrmType convert=CNV_FRM_NO;
DiracOpClover dirac(lat,f_field_out,f_field_in,arg,convert);
//cout << "B: " << site << endl;
//cout << "B: site: " << site[0] << ' ' << site[1] << ' ' << site[2] << ' ' << site[3] << endl;
dirac.SiteCloverMat(site,h_cps_clover_inv);
interface(h_quda_clover_inv_site,h_cps_clover_inv);
}
void fill_h_clover_inv_all(Lattice &lat, double *h_quda_clover_inv, int parity)
{
double *ptr=h_quda_clover_inv;
int nsites[4];
nsites[0]=GJP.XnodeSites();
nsites[1]=GJP.YnodeSites();
nsites[2]=GJP.ZnodeSites();
nsites[3]=GJP.TnodeSites();
int site[4];
cout << "A: " << site << endl;
for (site[3] = 0; site[3] < nsites[3]; ++(site[3])) {
for (site[2] = 0; site[2] < nsites[2]; ++(site[2])) {
for (site[1] = 0; site[1] < nsites[1]; ++(site[1])) {
site[0] = (site[3] + site[2] + site[1] + parity)%2;
for (; site[0] < nsites[0]; site[0] += 2) {
//cout << "A: site: " << site[0] << ' ' << site[1] << ' ' << site[2] << ' ' << site[3] << endl;
fill_h_clover_inv(lat,site,ptr);
ptr += CLOVER_MAT_SIZE;
}
}
}
}
}
The problem was with some uninitialised arguments being passed to DiracOpClover. Once we initialised CgArg properly,
CgArg cg_arg;
cg_arg.mass=1.0
everything was hunky dory!!
Thank for the help everyone.