I am implementing code for convolution in C++ (I know it exists already but I'm just doing it for practice since I'm a beginner), and while I can get the correct output, there are certain methods I'm trying that are giving unexpected output depending on how I access the values of the convolution that I store in an array and I'm not sure why.
The function code that works, whether I access the values by array indexing or with pointer incrementing, is:
void conv(int M, int* h, int L, int* x, int* y) {
int n, m = 0;
for (n = 0; n < L + M - 1; n++) {
for (m = std::max(0, n - L + 1); m <= std::min(n, M - 1); m++) {
*(y+n) += *(h + m) * *(x + n - m);
};
std::cout << "using array index: " << std::endl;
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
std::cout << std::endl;
std::cout << "using pointer: " << std::endl;
std::cout << "n = " << n << " " << "y = " << *(y+n) << " " << std::endl;
std::cout << std::endl;
//y++;
}
}
However, if I make slight changes to this (numbered below):
void conv(int M, int* h, int L, int* x, int* y) {
int n, m = 0;
for (n = 0; n < L + M - 1; n++) {
for (m = std::max(0, n - L + 1); m <= std::min(n, M - 1); m++) {
*y += *(h + m) * *(x + n - m); //[1]
};
std::cout << "using array index: " << std::endl;
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
std::cout << std::endl;
std::cout << "using pointer: " << std::endl;
std::cout << "n = " << n << " " << "y = " << *y << " " << std::endl; //[2]
std::cout << std::endl;
y++; //[3]
}
}
In this case, only accessing the values via pointer provides the correct output, while accessing it via array indexing provides random garbage.
My test code is:
int main()
{
const int M = 5; const int L = 6;
int y[M + L - 1] = {};
int x[L] = { 1, -2, 5, 3, 8, -4 };
int h[M] = { 1,2,3,4,5 };
int* yPtr = y; int* hPtr = h; int* xPtr = x;
conv(M, hPtr, L, xPtr, yPtr);
std::cout << "value after leaving conv" << std::endl;
for (int i = 0; i < M+L-1; i++) {
std::cout << "i = " << i << " " << "y = " << y[i] << std::endl;
}
}
which always provides the correct output even when accessing the array elements in the for loop of the conv provides the incorrect output.
For reference, the correct output is y = {1, 0, 4, 11, 26, 31, 53, 35, 24, -20}.
What am I doing wrong in the second example of conv to be getting the wrong values when using array indexing?
In the second version of the code, you are incrementing y as you go through the loop, so y[n] in the second version is equivalent to y[2*n] in the first. Once n reaches half the size of the array, y[n] is past the end of the array, thus garbage. *y is equivalent to y[0].
Your example is sufficiently weird to be a little difficult to read, but from your second version, this is fishy:
std::cout << "n = " << n << " " << "y = " << y[n] << " " << std::endl;
You're incrementing y as you go, so y[n] is going to go to weird places fast.
I saved Y as int * yOrig = y; and then used that, and I think I'm getting the output you expect, but I'm not sure.
I am trying to compute the time history of the velocity described by the equation:
dV/dt = g − (C_d/m) * V^2. g = 9.81, m = 1.0, and C_d = 1.5.
To do this I need to create a program in c++ that uses the Euler explicit method to numerically solve the equation. I am trying to find the velocity from t = 0 to t = 1 seconds with three different step sizes of delta_t = 0.05, 0.1, and 0.2 seconds. And then you are supposed to show your percent error to the analytical solution given as: V(t) = sqrt((m*g)/C_d) * tanh(sqrt((g*C_d)/m) * t).
My problem is I am not sure how to iterate through Euler's method multiple times with different time intervals. So far I have solved the analytical equation, but am unsure where to go from here. If anyone could help point me in the right direction it would be greatly appreciated.
#include <iomanip>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
double m = 1.0; // units in [kg]
double g = 9.81; // units in [m/s^2]
double C_d = 1.5; // units in [kg/m]
double t; // units in [s]
double v; // units in [m/s]
cout << "The velocity will be examined from the time t = 0 to t = 1 seconds." << endl;
cout << "Please select either 0.05, 0.1, or 0.2 to be the time interval:" << endl;
cin >> t;
cout << "You have chosen the time interval of: " << t << " seconds." << endl;
v = sqrt((m * g) / C_d) * tanh(sqrt((g * C_d) / m) * t);
cout << "The velecity at a time of "<< t << " seconds is equal to: " << v << " m/s." << endl;
return 0;
} ```
If you want to iterate over t with increments of A, calculating the result of the formula with each t, you would write a for loop.
#include <iostream>
int main()
{
double m = 1.0; // units in [kg]
double g = 9.81; // units in [m/s^2]
double C_d = 1.5; // units in [kg/m]
std::cout << "The velocity will be examined from the time t = 0 to t = 1 seconds." << std::endl;
std::cout << "Please select the time interval:" << std::endl;
std::cout << "1: 0.05" << std::endl;
std::cout << "2: 0.1" << std::endl;
std::cout << "3: 0.2" << std::endl;
double A = 0; // increment in for loop
int x;
std::cin >> x;
switch (x) { // check what the input is equal to
case 1: A = 0.05; break;
case 2: A = 0.1; break;
case 3: A = 0.2; break;
default: std::cout << "Unknown option!" << std::endl; return 1;
}
std::cout << "You have chosen the time interval of: " << A << " seconds." << std::endl;
std::cout << "Results of V(t):" << std::endl;
// this initializes a variable t as 0,
//and while t is lower than or equal to 1,
//it will increment it by a and execute the logic within the scope of the loop.
for (double t = 0; t < (1 + A); t += A) {
std::cout << "at t = " << t << ": " << sqrt((m*g) / C_d) * tanh(sqrt((g*C_d) / m) * t) << std::endl;
}
return 0;
}
Refer to https://beginnersbook.com/2017/08/cpp-for-loop/ for more information. Note: I've also introduced a switch statement into the code to prevent unknown values from being input. https://beginnersbook.com/2017/08/cpp-switch-case/
So I've made a basic polynomial class in C++ which stores the coefficients of these polynomials dynamically on the heap. I'm currently in the process of overloading operators so that I can add/subtract polynomials together in order to simplify them etc.
However I'm getting unexpected results when I try to overload the * operator. It looks like instead of returning the value of an index in the array it is returning the position of the array.
This is my *operator method in my .cpp file:
Polynomial Polynomial::operator*(Polynomial p) {
int maxDegree = (degree)+(p.degree - 1);
int *intArray3 = new int[maxDegree];
int i, j;
for (int i = 0; i < degree; i++) {
for (int j = 0; j < p.degree; j++) {
cout << getCoef(i) << " * " << p.getCoef(j) << " = " << getCoef(i)*p.getCoef(j) << endl;
intArray3[j] += (getCoef(i))*(p.getCoef(j));
cout << " intArray3[" << j << "] contains : " << intArray3[j] << endl;
}
}
return Polynomial(maxDegree, intArray3);}
The lines:
cout << getCoef(i) << " * " << p.getCoef(j) << " = " << getCoef(i)*p.getCoef(j) << endl;
and
cout << " intArray3[" << j << "] contains : " << intArray3[j] << endl;
return
10 * 1 = 10
intArray3[0] contains : -842150441
in my console. I'm assuming that the problem lies with my use of pointers somewhere but I can't for the life of me think why. I implemented this overload in a similar way to my + and - overloads and they work fine. Any assistance would be greatly appreciated. Cheers.
I'm trying to create an 2D array table in C++ with a for loop and this is my code below.
//receive user input
double nSideA = sSideA;
for( double x = nSideA; x < eSideA; x = x + incrementA){
cout << "a=" << fixed << setprecision(1) << setw(4) << nSideA << " ";
nSideA += incrementA;
} // table header
cout << "\n"; //spacing
for (double y = sSideB; y < eSideB; y = y + incrementB){
for( double x = sSideA; x < eSideA; x = x + incrementA){
sSideA += incrementA;
sSideB += incrementB;
hypo = sqrt( pow(sSideA,2) + pow(sSideB,2) );
cout << "b=" << fixed << setprecision(1) << setw(4) << sSideB << " ";
cout << fixed << setprecision(3) << setw(3) << hypo << " " << endl;
}} // content
My output for the table is something like :
b= 2.0 2.828
b= 3.0 4.243
b= 4.0 5.657
b= 5.0 7.071
b= 6.0 8.485
b= 7.0 9.899
with b not looping properly. (Printed all in a column thanks to Frax in the comments with endl;)
This is supposed to be a program that performs the Pythagoras Theorem. I intend for my output to be like
However, the results go wrong on the second loop where a[1][1] ends up at a[1][0] , a[2][2] ends up at a[2][0] and so on.
How do I fix my for loop to make it print a proper table?
Thank you.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
const double PI = 3.14159;
double rad = 0;
double area = 0;
double vol = 0;
int areaPi = 0;
int volPi = 0;
cout << setprecision(5) << fixed;
cout << setw(38) << left << "Enter radius for the sphere: " << right);
cin >> rad;
area = (4 * PI * (rad * rad));
vol = ((4.0/3.0) * PI * (rad * rad * rad));
areaPi = (4 * (rad *rad));
volPi = (4 * (rad * rad * rad));
cout << right << "Surface area of the sphere: " << setw(12) << area << " (" << areaPi << "\u03C0)";
cout << "\n";
cout << "The volume of the sphere: " << setw(14) << vol << " (" << volPi << "π/3)";
cout << "\n";
return 0;
}
Hi guys. So the problem I'm having is that when you enter a value for the radius (rad) variable the cursor wants to work its way from the left to the right when the user types resulting in double digit numbers being longer than the output columns.
It looks like this when the program runs and you enter anything longer than one digit:
//Enter radius for the sphere: 17
//Surface area of the sphere: 3631.67804 (1156π)
//The volume of the sphere: 20579.50889 (19652π/3)
I would like the 7 to line up with the column below it. I tried setting the width to one less than I had before & single digits end up one space too far to the left like so:
//Enter radius for the sphere: 4
//Surface area of the sphere: 201.06176 (64π)
//The volume of the sphere: 268.08235 (256π/3)
I would store the output into a set of strings. Then you could check and manipulate the data as needed. Alternatively you could calculate the offset of spaces you'd need before printing
// convert to string for digit count
std::string output_1 = std::to_string(x);
std::string output_2 = std::to_string(y);
int o_1_2_dist = output_1.size() - output_2.size(); // difference in digits
std::string padding_1, padding_2;
if (o_1_2_dist < 0)
padding_1 = std::string(abs(o_1_2_dist), ' ');
else
padding_2 = std::string(o_1_2_dist, ' ');
std::cout << padding_1 << output_1 << '\n' << padding_2 << output_2;
you'd want to adjust on of the output strings so it doesn't count the extra bits of the number you don't care about. Maybe do output_1 = std::to_string(floor(x)); or something like that so you don't count the digits after the decimal
This can be solved by calculating the length of the input. I used c++11's to_string to convert the resulting values to strings and find out their lengths. I haven't tried how portable that is. It seems to work under linux with gcc 6.1.1., but for some reason it did not work with the input, so I changed that part as well so that the users enters a std::string which gets converted to a double afterwards.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
const double PI = 3.14159;
double rad = 0;
double area = 0;
double vol = 0;
int areaPi = 0;
int volPi = 0;
int width_col1 = 40;
//cout.fill('.');
cout << setprecision(5) << fixed;
cout << left << setw(width_col1) << "Enter radius for the sphere: " << right;
std::string input;
cin >> input;
rad = stod(input);
area = (4 * PI * (rad * rad));
vol = ((4.0/3.0) * PI * (rad * rad * rad));
areaPi = (4 * (rad *rad));
volPi = (4 * (rad * rad * rad));
int indent = width_col1 + input.length() + 1;
cout << left << setw(indent - to_string(area).length()) << "Surface area of the sphere: " << area << " (" << areaPi << "\u03C0)" << std::endl;
cout << left << setw(indent - to_string(vol).length()) << "The volume of the sphere: " << vol << " (" << volPi << "π/3)" << std::endl;
return 0;
}
This solution resembles what C programmers would have done with printf.
I would love to learn why this did not work with the input.