Runge Kutta and PGPLOT - c++

Hi guys when I use this code (makefile not included) I am supposed to be getting two sinusoidal outputs graphed on the same set of axes but for some reason although the output data is accurate the graph is not. In face its not even a smooth curve, it has holes and cusps. Anyone have an idea as to why? Does it have something to do this the array I have written for the time axis? (Note beginner at coding)
#include <iostream>
#include <cmath>
#include <stdio.h>
#include "cpgplot.h"
//d2xdt2 = -(g/L)*sin(x)
//dwdt = -d2xdt2
//coeff = -(g/L)
//dxdt= w
float dxdt(float w)
{
return w;
}
float dwdt(float x, float coeff)
{
return coeff*sin(x);
}
int main(){
// Standard Variables
float wARR[5];
float xARR[5];
float tARR[5];
float w; //w = angular velocity
float x; //x = theta used in second order equation
float xo; //xo = theta initial
float wo = 0; //wo = initial angular velocity
float dt = 1; //h = step value
float g=9.8; //g = gravity
float L; //L = length of pendulum
float to = 0;
float t;
float time;
float kx1, kw1;
float kx2, kw2;
float kx3, kw3;
float kx4, kw4;
// Input Printing
std::cout << "\n";
std::cout << "Click ENTER key after each value. Please input: \n The initial angle (in decimal radians): "<<"\n";
std::cin >> xo;
std::cout << "The length of the pendulum (in meters)."<<"\n";
std::cin >> L;
std::cout << "\n";
// Specific Variable Declarations
float coeff=-(g/L);
//Checkpoint values
std::cout << "CHECKPOINT VALUES: ";
std::cout << "\n";
std::cout << "Confirming your initial angle is: " << xo << " radian(s)";
std::cout << "\n";
std::cout << "Confirming the length is: " << L << " meters(s)";
std::cout << "\n";
std::cout << "Confirming the gravity constant is: " << g << " meters/sec";
std::cout << "\n";
std::cout << "Coeff (-g/L): " << coeff;
std::cout << "\n";
std::cout << "\n";
std::cout << "Insert the time (in seconds) you want to learn some cool stuff about your pendulum: "<<"\n";
std::cin >> time;
std::cout << "\n";
//Array info and Runge Kutta
xARR[0] = xo;
wARR[0] = 0;
tARR[0] = 0;
time=time+1;
for (int i = 0; i < time ; i++){
x = xARR[i];
w = wARR[i];
t = tARR[i];
kx1=dt*dxdt(w);
kw1=dt*dwdt(x,coeff);
kx2=dt*dxdt(w+kw1*0.5);
kw2=dt*dwdt(x+kx1*0.5, coeff);
kx3=dt*dxdt(w+kw2*0.5);
kw3=dt*dwdt(x+kx2*0.5, coeff);
kx4=dt*dxdt(w+kw3);
kw4=dt*dwdt(x+kx3, coeff);
std::cout << "\n";
std::cout << "RUNGE KUTTA VALUES: at " << i << " second(s)" << "\n";
std::cout << "kx1: " << kx1 << "\n";
std::cout << "kx2: " << kx2 << "\n";
std::cout << "kx3: " << kx3 << "\n";
std::cout << "kx4: " << kx4 << "\n";
std::cout << "kw1: " << kw1 << "\n";
std::cout << "kw2: " << kw2 << "\n";
std::cout << "kw3: " << kw3 << "\n";
std::cout << "kw4: " << kw4 << "\n";
xARR[i+1] = xo + (1.0/6.0)*(kx1 + 2*kx2 + 2*kx3 + kx4);
wARR[i+1] = wo + (1.0/6.0)*(kw1 + 2*kw2 + 2*kw3 + kw4);
std::cout << "FINAL VALUES: at " << i << " second(s)" << "\n";
std::cout << "The angle is: " << x << " radian(s)";
std::cout << "\n";
std::cout << "The velocity is: " << w << " radians/s";
std::cout << "\n";
std::cout << "\n";
std::cout << "-----------------------------------------------------\n";
std::cout << "\n";
}
// Graphing with arrays
//To see the time dependence, let's suppose you have two arrays: one for w and one for x. Then the values x[i] and w[i] entry describe the position and velocity of your pendulum at time t_i.
// Open a plot window
if (!cpgopen("/XWINDOW")) return 1;
// Set-up plot axes
// M_PI is defined in cmath
cpgenv(0,time,-1,1,0,1);
// Label axes
cpglab("time", "angle", "RED = Angle BLUE = Velocity");
cpgsci(2); //RED
cpgline(10,tARR, xARR);
cpgsci(4); //BLUE
cpgline(10,tARR, wARR);
cpgclos();
}

Related

Very basic calculator issues

I'm a fairly new to c++. I'm trying to create a very basic calculator and the results I'm getting are completely wrong. I've come to a standstill after 2 hours of trying everything in my knowledge. What am I doing wrong?
#include <iostream>
using namespace std;
int main()
{
int a = 0.0;
int b = 0.0;
float sum = 'a' + 'b';
float diff = 'a' - 'b';
float prod = 'a' * 'b';
float quot = 'a' / 'b';
float rem = 'a' % 'b';
//Input
cout << "Enter a number: " << endl;
cin >> a;
cout << "Enter another number: " << endl;
cin >> b;
cout << a << " + " << b << " = " << sum <<endl;
cout << a << " - " << b << " = " << diff <<endl;
cout << a << " / " << b << " = " << quot <<endl;
cout << a << " * " << b << " = " << prod <<endl;
cout << a << " % " << b << " = " << rem <<endl;
return 0;
}
you are calculating with character literals. 'a' is not the same as a here.
remove the quotes when calculating, but add them when you print the actual literal "a"
float sum = 'a' + 'b';
You are calculating the ASCII value of the character "a" (which is 65) with the ASCII value of "b" (which is 66)
It should be
float sum = a + b;
instead.
When you print the values, you did the reverse:
cout << a << " + " << b << " = " << sum <<endl;
You want it to be
cout << "a" << " + " << "b" << " = " << sum <<endl;
instead. You want to print characters for the equation and only a number for the result.
You also calculate the values of a and b before they have an actual value.
You should put the calculation after you enter them.
Fixed, by moving the calculations after the input; and by using variables, not literals.
#include <iostream>
using namespace std;
int main()
{
int a = 0.0;
int b = 0.0;
//Input
cout << "Enter a number: " << endl;
cin >> a;
cout << "Enter another number: " << endl;
cin >> b;
float sum = a + b;
float diff = a - b;
float prod = a * b;
float quot = a / b;
float rem = a % b;
cout << a << " + " << b << " = " << sum <<endl;
cout << a << " - " << b << " = " << diff <<endl;
cout << a << " / " << b << " = " << quot <<endl;
cout << a << " * " << b << " = " << prod <<endl;
cout << a << " % " << b << " = " << rem <<endl;
return 0;
}

C++: How can make each of the answers of my calculation program align?

Here's my code:
#include<iostream>
int main() {
int width, length, sq_cm, sq_m{}, sq_in, sq_ft, cm, m, in, ft;
std::cout << "Find the Area and Perimeter of a Rectangle \n\n";
std::cout << "Input the length of the rectangle : \b";
std::cin >> length;
std::cout << "Find the width of the rectangle : \b";
std::cin >> width;
sq_cm = (length * width);
sq_m = (sq_cm / 100);
sq_in = (sq_m * 39.37);
sq_ft = (sq_in / 12);
cm = (length + width);
m = (cm / 100);
in = (m * 39.37);
ft = (in / 12);
std::cout << "Area :" << sq_cm << std::endl;
std::cout << sq_m << std::endl;
std::cout << sq_in << std::endl;
std::cout << sq_ft << std::endl;
std::cout << "Perimeter :" << cm << std::endl;
std::cout << m << std::endl;
std::cout << in << std::endl;
std::cout << ft << std::endl;
return 0;
Here's how it looks like when I debugged it
Find the Area and Perimeter of a Rectangle
Input the length of the rectangle :87
Find the width of the rectangle :68
Area :5916
59
2322
193
Perimeter :155
1
39
3
Here's what I want it to look like
Find the Area and Perimeter of a Rectangle
Input the length of the rectangle :87
Find the width of the rectangle :68
area:5916 sq cm
59 sq m
2322 sq in
193 sq ft
Perimeter: 155 cm
1 m
39 in
3 ft
To format your text texts try something like this:
using \t to "tab" the output.
And like Sugar sad in the comments, is better to use "\n" instead of endl
#include<iostream>
int main() {
int width, length, sq_cm, sq_m{}, sq_in, sq_ft, cm, m, in, ft;
std::cout << "Find the Area and Perimeter of a Rectangle \n\n";
std::cout << "Input the length of the rectangle : \b";
std::cin >> length;
std::cout << "Find the width of the rectangle : \b";
std::cin >> width;
sq_cm = (length * width);
sq_m = (sq_cm / 100);
sq_in = (sq_m * 39.37);
sq_ft = (sq_in / 12);
cm = (length + width);
m = (cm / 100);
in = (m * 39.37);
ft = (in / 12);
std::cout << "\tArea :\n";
std::cout << "\t" << sq_cm << "\n";
std::cout << "\t" << sq_m << "\n";
std::cout << "\t" << sq_in << "\n";
std::cout << "\t" << sq_ft << "\n";
std::cout << "\tPerimeter :\n";
std::cout << "\t" << cm << "\n";
std::cout << "\t" << m << "\n";
std::cout << "\t" << in << "\n";
std::cout << "\t" << ft << "\n";
return 0;
}
It will be like this:
Find the Area and Perimeter of a Rectangle
Input the length of the rectangle :87
Find the width of the rectangle :68
Area:
5916
59
2322
193
Perimeter:
155
1
39
3

How to print the and update the scoreboard on the same line here?

#include <iostream>
#include <cstdlib>
#include <iomanip>
int Human_Roll() {
int num1;
srand(time(0));
num1 = (1 + rand() % 6);
return num1;
}
int Human_Roll_2() {
int num2;
num2 = (1 + rand() % 6);
return num2;
}
int Computer_Roll() {
int num3;
num3 = (1 + rand() % 6);
return num3;
}
int Coumputer_Roll_2() {
int num4;
num4 = (1 + rand() % 6);
return num4;
}
int main() {
int counter1 = 0, counter2 = 0;
char start;
for (int i = 1; i <= 150; i++) {
std::cin >> start;
int x1{ Human_Roll() };
int x2{ Human_Roll_2() };
int y1{ Computer_Roll() };
int y2{ Coumputer_Roll_2() };
int x;
int y;
x = x1 + x2;
y = y1 + y2;
std::cout << "\nYou: " << x1 << " + " << x2 << " = " << x << "\n\n";
std::cout << "Computer: " << y1 << " + " << y2 << " = " << y << "\n";
if (x > y) {
std::cout << "\nYou win." << "\n";
++counter1;
}
if (y > x) {
std::cout << "\nYou lose. " << "\n";
++counter2;
}
if (x == y) {
std::cout << "\nDraw. " << "\n";
counter1 += 0;
counter2 += 0;
}
std::cout << " Scoreboard: " << counter1 << " - " << counter2 << "\n";
if (counter1 == 7) {
std::cout << "\n\n Victory! " << "\n";
break;
}
if (counter2 == 7) {
std::cout << "\n\n Loss! " << "\n";
break;
}
}
This is a supposed to be a dice game that calculates the sum of two randomly generated sides of the 6 sided dices. It does it two times and compares the sums to pick the winner with the bigger sum, and it should print out the scoreline every time the the winner is declared. My question is, how can I make the scoreline be updated on the same line as the game continues and not print "scoreboard x - y " every time the round is finished?
Hi from what I' m understanding you want o clear the console like this std::cout << "\033[2J\033[1;1H"; so when you roll the dices again the code comes in the same place but before you do this you need to stop the console make it wait for input and say something like "Press enter to play again" then the console clears and the next game comes in the same place or you can use something like Sleep(milliseconds); before cleaning.
Hope this is what you looking for.
As #enhzflep said this will end up being more than complicated solution for the system dependent code.
However the easy and quick solution is for visually having the same line being updated is to create many empty lines for every for loop iteration.
for (int n = 0; n < 50; n++)
{
std::cout << "\n";
}
As i said earlier this is the best c++ could do when there is no system information available. Using the standard commands.
updated for loop would look like
for (int i = 1; i <= 150; i++) {
int x1{ Human_Roll() };
int x2{ Human_Roll_2() };
int y1{ Computer_Roll() };
int y2{ Coumputer_Roll_2() };
int x;
int y;
x = x1 + x2;
y = y1 + y2;
std::cout << " ----- Game " << i << " -----";
std::cout << "\nYou: " << x1 << " + " << x2 << " = " << x << "\n";
std::cout << "Computer: " << y1 << " + " << y2 << " = " << y << "\n";
if (x > y) {
std::cout << "\nYou win." << "\n";
++counter1;
}
if (y > x) {
std::cout << "\nYou lose. " << "\n";
++counter2;
}
if (x == y) {
std::cout << "\nDraw. " << "\n";
counter1 += 0;
counter2 += 0;
}
std::cout << "---------------------------------------------"
std::cout << "Scoreboard: " << counter1 << " - " << counter2 << "\n";
if (counter1 == 7) {
std::cout << "\n\n Victory! " << "\n";
break;
}
if (counter2 == 7) {
std::cout << "\n\n Loss! " << "\n";
break;
}
for (int n = 0; n < 50; n++)
{
std::cout << "\n";
}
}
There are other ways to do it such as
Sysetm call to clear the terminal
but this method not safe why
The standard way to print end lines
Using the curser library #include <curses.h>
Advantage it is a cross-platform but can not be mixed with standard I/O

Setting up precision C++

So, i'm attempting to set the precision for input values in my code. I want the values to be printed with two decimal points afterwards of precision though i'm not exactly sure how.
Here's my code.
#include <iostream>
#include <iomanip>
float uphill, wellD, waterLvl, buckVol;
float buckAscRate, downHill, volume;
float last;
float timeReq;
int scene = 1;
void timeRequired()
{
std::setw(2);
std::setprecision(2);
std::cout << "Scenario " << scene << ":" << std::endl;
std::cout << "up hill" << " " << uphill << " sec" << std::endl;
std::cout << "well diamter" << " " << wellD << " in" << std::endl;
std::cout << "water level" << " " << waterLvl << " in" << std::endl;
std::cout << "bucket volume" << " " << buckVol << " cu ft" << std::endl;
std::cout << "bucket ascent rate" << " " << buckAscRate << " in/sec" << std::endl;
std::cout << "down hill" << " " << downHill << " sec" << std::endl;
std::cout << "required volume" << " " << volume << " cu ft" << std::endl;
timeReq = (uphill + downHill);
std::cout << "TIME REQUIRED" << " " << timeReq << " sec" << std::endl;
std::cout << " " << std::endl;
}
void scenarioCONT()
{
do
{
std::cin >> wellD;
std::cin >> waterLvl;
std::cin >> buckVol;
std::cin >> buckAscRate;
std::cin >> downHill;
std::cin >> volume;
std::cin >> last;
if (uphill <= 1) uphill = 2;
if (wellD <= 0) wellD = 1;
if (waterLvl <= 0) waterLvl = 1;
if (buckVol <= 0) buckVol = 1;
if (buckAscRate <= 0) buckAscRate = 1;
if (downHill <= 0) buckAscRate = 1;
if (volume <= 0) volume = 1;
if (last > 1)
{
uphill = last;
scenarioCONT();
}
} while (last != 0);
}
void scenario()
{
do
{
std::cin >> uphill;
std::cin >> wellD;
std::cin >> waterLvl;
std::cin >> buckVol;
std::cin >> buckAscRate;
std::cin >> downHill;
std::cin >> volume;
std::cin >> last;
if (uphill <= 1) uphill = 2;
if (wellD <= 0) wellD = 1;
if (waterLvl <= 0) waterLvl = 1;
if (buckVol <= 0) buckVol = 1;
if (buckAscRate <= 0) buckAscRate = 1;
if (downHill <= 0) buckAscRate = 1;
if (volume <= 0) volume = 1;
if (last > 1)
{
timeRequired();
uphill = last;
scenarioCONT();
}
scene++;
timeRequired();
} while (last != 0);
}
int main()
{
scenario();
system("pause");
}
I've been told to use ionmanip to set the precision, though i'm not 100% on how to do it. Any suggestions?
You can use std::setprecision function. The below example is directly taken from http://www.cplusplus.com/reference/iomanip/setprecision/
double f =3.14159;
std::cout << std::setprecision(5) << f << '\n';
std::cout << std::setprecision(9) << f << '\n';
If you want to output 2 decimal digits, you should use std::fixed, together with std::setprecision().
Take a look here.
For easier understanding, here is an example:
cout << setprecision(2)<< 3.1415; outputs 3.1 (2 digits in total) and
cout << setprecision(2)<<fixed<< 3.1415; outputs 3.14 (2 digits after floating point)

Gaussian elimination issue in solving the matrix

float aMatrix[10][11];
float bMatrix[10];
// called as such...
solveMatrix(aMatrix, bMatrix, actualCol);
float* solveMatrix(float aMatrix[][DEFCOLS+1],float bMatrix[DEFCOLS], size_t cols){
std::cout << "\nInside solveMatrix...: " << endl;
size_t N2 = cols;
std::cout << "\N2 is...: " << N2 << endl;
for(size_t p=0; p<N2; p++){
//std::cout << "\nInside 1st for loop...: " << endl;
// find pivot row and swap
int max = p;
for(size_t i=p+1; i<N2; i++){
//std::cout << "\nInside 2nd for loop...: " << endl;
if ( abs(aMatrix[i][p]) > abs(aMatrix[max][p]) ){
max = i;
}
}
//std::cout << "\nJust b4 all the swapping...: " << endl;
float temp[] = { *aMatrix[p] };
*aMatrix[p] = *aMatrix[max];
*aMatrix[max] = *temp;
float t = bMatrix[p];
bMatrix[p] = bMatrix[max];
bMatrix[max] = t;
//std::cout << "\nDone all the swapping...: " << endl;
if ( abs(aMatrix[p][p]) <= MINISCULE) {
//std::cout << "***** Error matrix value too small. Matrix is singular" << endl;
//exit;
}
//std::cout << "\nJust the pivoting...: " << endl;
// Pivot /in A and b
for(size_t i=p+1; i<N2; i++){
//std::cout << "\nInside the 1st pivoting loop...: " << endl;
//std::cout << "\nAbout to do the [aMatrix[p][p]] division in back subst..: " << endl;
float alpha = aMatrix[i][p] / aMatrix[p][p];
bMatrix[i] = alpha * bMatrix[p];
for(size_t j=p; j<N2; j++){
//std::cout << "\nInside the 2nd pivoting loop...: " << endl;
aMatrix[i][j] -= alpha * aMatrix[p][j];
}
}
std::cout << "\nAbout to do the back subst..: " << endl;
// back subst.
float outMatrix[DEFROWS] = {0.0};
for(size_t i=N2-1; i>=0; i--){
std::cout << "\nInside the 1st back subst for loop..: " << endl;
float sum = 0.0;
for(size_t j=i+1; j<N2; j++){
std::cout << "\nInside the 2nd back subst for loop..: " << endl;
sum += aMatrix[i][j] * outMatrix[j];
}
std::cout << "\nAbout to do the [aMatrix[i][i]] division in back subst..: " << endl;
std::cout << "\n*outMatrix[i]: " << outMatrix[i] << endl;
std::cout << "\n( bMatrix[i] - sum ) : " << ( bMatrix[i] - sum ) << endl;
std::cout << "\n****aMatrix[i][i] : " << aMatrix[i][i] << endl;
if (aMatrix[i][i] > 0){
std::cout << "\nDid the division [aMatrix[i][i]] > 0 division in back subst..: " << endl;
std::cout << "\n*outMatrix[i]: " << outMatrix[i] << endl;
std::cout << "\n( bMatrix[i] - sum ) : " << ( bMatrix[i] - sum ) << endl;
std::cout << "\naMatrix[i][i] : " << aMatrix[i][i] << endl;
outMatrix[i] = ( bMatrix[i] - sum ) / aMatrix[i][i];
std::cout << "\nDid the division [aMatrix[i][i]] > 0 division in back subst..DONE: " << endl;
}else {
std::cout << "\nDid the divirion [aMatrix[i][i]] = 0 division in back subst..: " << endl;
outMatrix[i] = 0.0;
std::cout << "\nDid the divirion [aMatrix[i][i]] = 0 division in back subst..DONE: " << endl;
}
std::cout << "\nDid the [aMatrix[i][i]] division in back subst..: " << endl;
}
std::cout << "\nLeft the back subst for loops..: " << endl;
return outMatrix;
}
} // end solveMatrix()
My problem is that my program seems to run but seems to run past the end of the matrix and crashes. Plus I am getting some large exponential numbers and the largest numbers that I have in the array is from 1-10.
here is a screenshot of the output: Can't seem to paste from the snipping tool. But the problem seem to start after the "back substitution" starts.
Any help would be appreciated.
I am not sure what all the problems are, but one clear issue is your outMatrix. You are returning a pointer to a local array. The array is being destroyed at the end of the function. The pointer you are returning is now junk.
Change this line:
float outMatrix[DEFROWS] = {0.0};
To:
float* outMatrix = new float[DEFROWS];
Then you need to zero that out.
NOTE: It would be better if you used a vector<float> and returned that, but you wrote it with a raw pointer so I am answering with raw pointer. Raw pointers lead to memory leaks. They should be avoided when possible. With modern C++ it is rarely necessary to allocate a raw pointer.
EDIT:
See Effective C++ Item #31
EDIT2: Changing to use vector, if your compiler supports the move operators and constructors as defined in the C++11 standard, then returning a vector is a cheap operation.
std::vector<float> solveMatrix(/* Your arguments */)
{
std::vector<float> outMatrix(DEFROWS, 0.0);
// Your code
return outMatrix;
}