C++ Trapezoidal Integration Function Returning Negative Numbers when it shouldn't - c++

I am using the following function written in C++, whose purpose is to take the integral of one array of data (y) with respect to another (x)
// Define function to perform numerical integration by the trapezoidal rule
double trapz (double xptr[], double yptr[], int Npoints)
{
// The trapzDiagFile object and associated output file are how I monitor what data the for loop actually sees.
std::ofstream trapzDiagFile;
trapzDiagFile.open("trapzDiagFile.txt",std::ofstream::out | std::ofstream::trunc);
double buffer = 0.0;
for (int n = 0; n < (Npoints - 1); n++)
{
buffer += 0.5 * (yptr[n+1] + yptr[n]) * (xptr[n+1] - xptr[n]);
trapzDiagFile << xptr[n] << "," << yptr[n] << std::endl;
}
trapzDiagFile.close();
return buffer;
}
I validated this function for the simple case where x contains 100 uniformly spaced points from 0 to 1, and y = x^2, and it returned 0.33334, as it should.
But when I use it for a different data set, it returns -3.431, which makes absolutely no sense. If you look in the attached image file, the integral I am referring to is the area under the curve between the dashed vertical lines.
It's definitely a positive number.
Moreover, I used the native trapz command in MATLAB on the same set of numbers and that returned 1.4376.
In addition, I translated the above C++ trapz function into MATLAB, line for line as closely as possible, and again got 1.4376.
I feel like there's something C++ related I'm not seeing here. If it is relevant, I am using minGW-w64.
Apologies for the vagueness of this post. If I knew more about what kind of issue I am seeing, it would be easier to be concise about it.
Plot of the dataset for which the trapz function (my homemade C++ version) returns -3.431:

Please check the value of xptr[Npoints - 1]. It may be less than xptr[Npoints - 2], and was not included in the values that you output.

Related

Prevent a user from entering a value which would cause integer to overflow

I'm very new to C++ programming, and have written a simple program to calculate the factorial of an integer provided by the user. I am attempting to account for inputs which would cause an error, or do not make sense (e.g. I have accounted for input of a negative number/-1 already). I want to print out an error if the user enters a number whose factorial would be larger than the maximum integer size.
I started with:
if(factorial(n) > INT_MAX)
std::cout << "nope";
continue
I tested this with n = ~25 or 26 but it doesn't prevent the result from overflowing and printing out a large negative number instead.
Second, I tried assigning this to a variable using a function from the 'limits.h' header and then comparing the result of factorial(n) against this. Still no luck (you can see this solution in the code sample below).
I could of course assign the result to a long and test against that but you wouldn't have to go very far until you started to wrap around that value, either. I'd prefer to find a way to simply prevent the value from being printed if this happens.
#include <iostream>
#include <cstdlib>
#include <limits>
int factorial(int n)
{
auto total = 1;
for(auto i = 1; i <= n; i++)
{
total = total * i; //Product of all numbers up to n
}
return total;
}
int main()
{
auto input_toggle = true;
auto n = 0;
auto int_max_size = std::numeric_limits<int>::max();
while(input_toggle = true)
{
/* get user input, check it is an integer */
if (factorial(n) > int_max_size)
{
std::cout << "Error - Sorry, factorial of " << n << " is larger than \nthe maximum integer size supported by this system. " << std::endl;
continue;
}
/* else std::cout << factorial(n) << std::endl; */`
As with my other condition(s), I expect it to simply print out that small error message and then continue asking the user for input to calculate. The code does work, it just continues to print values that have wrapped around if I request the factorial of a value >25 or so. I feel this kind of error-checking will be quite useful.
Thanks!
You are trying to do things backwards.
First, no integer can actually be bigger than INT_MAX, by definition - this is a maximum value integer can be! So your condition factorial(n) > int_max_size is always going to be false.
Moreover, there is a logical flaw in your approach. You calculate the value first and than check if it is less than maximum value allowed. By that time it is too late! You have already calculated the value and went through any overflows you might have encountered. Any check you might be performing should be performed while you are still doing your calculations.
In essence, you need to check if multiplying X by Z will be within allowed range without actually doing the multiplication (unfortunately, C++ is very strict in leaving signed integer overflow undefined behavior, so you can't try and see.).
So how do you check if X * Y will be lesser than Z? One approach would be to divide Z by Y before engaging in calculation. If you end up with the number which is lesser than X, you know that multiplying X by Y will result in overflow.
I believe, you know have enough information to code the solution yourself.

Multiply numbers which are divisible by 3 and less than 10 with a while loop in c++?

In C++, I should write a program where the app detects which numbers are divisible by 3 from 1 till 10 and then multiply all of them and print the result. That means that I should multiply 3,6,9 and print only the result, which is 162, but I should do it by using a "While" loop, not just multiplying the 3 numbers with each other. How should I write the code of this? I attached my attempt to code the problem below. Thanks
#include <iostream>
using namespace std;
int main() {
int x, r;
int l;
x = 1;
r = 0;
while (x < 10 && x%3==0) {
r = (3 * x) + 3;
cout << r;
}
cin >> l;
}
Firstly your checking the condition x%3 == 0 brings you out of your while - loop right in the first iteration where x is 1. You need to check the condition inside the loop.
Since you wish to store your answer in variable r you must initialize it to 1 since the product of anything with 0 would give you 0.
Another important thing is you need to increment the value of x at each iteration i.e. to check if each number in the range of 1 to 10 is divisible by 3 or not .
int main()
{
int x, r;
int l;
x = 1;
r = 1;
while (x < 10)
{
if(x%3 == 0)
r = r*x ;
x = x + 1; //incrementing the value of x
}
cout<<r;
}
Lastly I have no idea why you have written the last cin>>l statement . Omit it if not required.
Ok so here are a few hints that hopefully help you solving this:
Your approach with two variables (x and r) outside the loop is a good starting point for this.
Like I wrote in the comments you should use *= instead of your formula (I still don't understand how it is related to the problem)
Don't check if x is dividable by 3 inside the while-check because it would lead to an too early breaking of the loop
You can delete your l variable because it has no affect at the moment ;)
Your output should also happen outside the loop, else it is done everytime the loop runs (in your case this would be 10 times)
I hope I can help ;)
EDIT: Forget about No.4. I didn't saw your comment about the non-closing console.
int main()
{
int result = 1; // "result" is better than "r"
for (int x=1; x < 10; ++x)
{
if (x%3 == 0)
result = result * x;
}
cout << result;
}
or the loop in short with some additional knowledge:
for (int x=3; x < 10; x += 3) // i know that 3 is dividable
result *= x;
or, as it is c++, and for learning purposes, you could do:
vector<int> values; // a container holding integers that will get the multiples of 3
for (int x=1; x < 10; ++x) // as usual
if ( ! x%3 ) // same as x%3 == 0
values.push_back(x); // put the newly found number in the container
// now use a function that multiplies all numbers of the container (1 is start value)
result = std::accumulate(values.begin(), values.end(), 1, multiplies<int>());
// so much fun, also get the sum (0 is the start value, no function needed as add is standard)
int sum = std::accumulate(values.begin(), values.end(), 0);
It's important to remember the difference between = and ==. = sets something to a value while == compares something to a value. You're on the right track with incrementing x and using x as a condition to check your range of numbers. When writing code I usually try and write a "pseudocode" in English to organize my steps and get my logic down. It's also wise to consider using variables that tell you what they are as opposed to just random letters. Imagine if you were coding a game and you just had letters as variables; it would be impossible to remember what is what. When you are first learning to code this really helps a lot. So with that in mind:
/*
- While x is less than 10
- check value to see if it's mod 3
- if it's mod 3 add it to a sum
- if not's mod 3 bump a counter
- After my condition is met
- print to screen pause screen
*/
Now if we flesh out that pseudocode a little more we'll get a skeletal structure.
int main()
{
int x=1//value we'll use as a counter
int sum=0//value we'll use as a sum to print out at the end
while(x<10)//condition we'll check against
{
if (x mod 3 is zero)
{
sum=x*1;
increment x
}
else
{
increment x
}
}
//screen output the sum the sum
//system pause or cin.get() use whatever your teacher gave you.
I've given you a lot to work with here you should be able to figure out what you need from this. Computer Science and programming is hard and will require a lot of work. It's important to develop good coding habits and form now as it will help you in the future. Coding is a skill like welding; the more you do it the better you'll get. I often refer to it as the "Blue Collar Science" because it's really a skillset and not just raw knowledge. It's not like studying history or Biology (minus Biology labs) because those require you to learn things and loosely apply them whereas programming requires you to actually build something. It's like welding or plumbing in my opinion.
Additionally when you come to sites like these try and read up how things should be posted and try and seek the "logic" behind the answer and come up with it on your own as opposed to asking for the answer. People will be more inclined to help you if they think you're working for something instead of asking for a handout (not saying you are, just some advice). Additionally take the attitude these guys give you with a grain of salt, Computer Scientists aren't known to be the worlds most personable people. =) Good luck.

Filling an array or struct by file in C++

I'm writing a simple 2D game in C++ (a language that is still quite new to me) using DirectX that involves a grid of 26x26 tiles sorted in a Cartesian-like manner - with the origin being the top leftmost space at 0,0. Each tile needs to contain the values:
int tileX (from 0 to 25)
int tileY (from 0 to 25)
int tileType (0 is empty)
int tileState
These values will be stored in a text file stage_n.txt (228 lines long) which is formatted like the following:
2 2 1
3 2 1
6 2 1
7 2 1
10 2 1
11 2 1
...
Each set of tile values are separated by a new line, while each value is separated by a space. The first value is tileX, the second value is tileY, the third value is tileType. All tiles are initially assumed to have a tileState of 8.
These values will be looped through to draw the stage at the start of the game, and will be changed often in the code.Note that only tiles that are occupied are listed in the file. Tiles that are empty are not listed.
My first thought was to use a multidimensional array tileMap[25][25][1] like the following:
tileMap[0] = 0 (X value) // All tiles on line X0
tileMap[0][0] = 0 (Y value) // First tile on line 0 (at Y0)
tileMap [0][0][0] // Tile type
tileMap [0][0][1] // Tile state
tileMap[0][1] = 1 (Y value) // Second tile on line 0 (at Y1)
tileMap [0][1][0] // Tile type
tileMap [0][1][1] // Tile state
... through to 25 (the last tile on line 0)
tileMap[1] = 1 (X value) // All tiles on line X1
tileMap[1][0] = 0 (Y value)
...
tileMap[1][0] = 1 (Y value)
...
...
... through to 25 (the last line)
But I was also considering using a structure:
struct tileData{
int tileX;
int tileY;
int tileType;
int tileState;
} tile[676]; // 676 is the total amount of tiles.
Going back to my question; in this situation, would it be more efficient to use a struct or an array? How would I go about initializing/filling the easier option using data in the above text file? I've tried to imitate many examples online (that have used ifstream), but none of them have seemed to work.
This question has probably been answered a lot, but I just can't get my head around how to do it. I hope this makes enough sense. Thanks!
EDIT: Additionally, where should I place my text file if I'm using VS2013?
I doubt there would be any different in performance, since both accessing an array and accessing a member of a struct just involve accessing some baked-in offset from some address. If it really matters because you've discovered this code to be a bottleneck, then you'll need to do some performance measures. I can almost guarantee that the compiled code will be identical in either case.
Anyway, it looks to me like it would be most appropriate to use a struct. While all the members of the struct are the same type, they do not have the same meaning. It's certainly possible that they could have different types. A struct nicely groups together these different yet related values.
Reading into your 1D array should be as simple as:
std::ifstream file("stage_n.txt");
int i = 0;
while (file >> tile[i].tileX
>> tile[i].tileY
>> tile[i].tileType) {
tile[i].tileState = 0;
++i;
}
There's no reason you can't have a 2D array of structs, though. That would better represent your grid. In that case, you would just need to keep track of an x and y position as you read from the file (instead of i).
The file reading code above doesn't do much in the way of error checking. If you want to be precise, you should consider what exactly should be valid. For example, the above code would still accept the data even if it were all on one line. If you want to read the file on a line-by-line basis, you'll need to use std::getline and then parse each line.
i would use a 2d array of Tile objects (or std::vector or std::array, always preferred to naked arrays)
struct Tile
{
int tileType;
int tileState;
}
Tile grid[25][25];
dont put the X/Y of the tile in the struct. This knowledge is implicitly encoded in its position in the array
I think there is no difference in performance between an array and a struct. But there is a difference in better code - use the struct tilData and write a istream-operator for it.
std::istream& operator>>( std::istream& in, tileData& td )
{
if( in >> td.tileX >> td.tileY >> td.tileType )
td.tileState = 8;
return in;
}
You can read it in this way:
size_t n = 0;
for( ; file >> tile[n]; ++n )
;
if( file.eof() ) // check whether End Of File is reached
{
cout << "Ok " << n << "Tiles read\n";
}

calculating w coefficients for iir filter

I am trying to implement an IIR filter I have designed in Matlab into a c++ program to filter out an unwanted signal from a wave file. The fdatool in Matlab generated this C header to use (it is a bandstop filter):
#include "tmwtypes.h"
/*
* Expected path to tmwtypes.h
* C:\Program Files (x86)\MATLAB\R2013a Student\extern\include\tmwtypes.h
*/
const int al = 7;
const real64_T a[7] = {
0.9915141178644, -5.910578456199, 14.71918523779, -19.60023964796,
14.71918523779, -5.910578456199, 0.9915141178644
};
const int bl = 7;
const real64_T b[7] = {
1, -5.944230431733, 14.76096188047, -19.60009655976,
14.67733658492, -5.877069568864, 0.9831002459245
};
After hours of exhausting research, I still can't figure out the proper way to use these values to determine the W values and then how to use those W values to properly calculate my Y outputs. If anyone has any insight into the ordering these values should be used to do all these conversions, it would be a major help.
All the methods I've developed and tried to this point do not generate a valid wave file, the header values all translate correctly, but everything beyond cannot be evaluated by a media player.
Thanks.
IIR filters work this way:
Assuming an array of samples A and and array of ceof named 'c' the result array B will be:
B[i] = (A[i] * c[0]) + (B[i-1] * c[1]) + ... + (B[n] * c[n])
Note that only the newest element is taken from A.
This is easier to do in-place, just update A as you move along.
These filter coefs are very violent, are you sure you got them right?
The first one is also symmetrical which probably indicates it's an FIR filter.
It appears to me that you have a 3 pole IIR filter with the coefficients given for an Nth order implementation (as opposed to a series of 2nd order sections). Since this is a band reject (or band pass) the polynomial order is twice the pole count.
I am not sure what you mean by W values, unless you are trying to evaluate the frequency response of this filter.
To calculate the Y values, as you put it, see this link for code on implementing IIR filters. See the Nth order implementation code in particular.
http://www.iowahills.com/A7ExampleCodePage.html
BTW: I assumed these were Nth order coefficients and simulated them. I got a 10 dB notch at 0.05 Pi. Sound about right?
where
B6 = 0.9915141178644
.
.
.
b0 = 0.9915141178644
a6 = 0.9831002459245
.
.
.
a0 = 1
Also, you may want to post a question like this on:
https://dsp.stackexchange.com/

How to have C++ solve the equation for an input value?

I am stuck trying to figure out a way using C++ to solve a situation where the user inputs a value using cin and then have the computer solve for a way to get the value of cin, given that the format is given. a super fast example is written below.. yes i know there is a lot of code missing... but the concept is there..
int x;
int y;
int w;
int x = 30 < w < 50;
int y = 60 < w < 90;
cin >> input;
x + y = input;
cout << x;
cout << y;
Naturally though x + y cant be on the lvalue on the right. so i cant just write x + y = input.. so how would i have it solve x + y = input? Additionally I want x and y to be between the numbers listed, which limits the numbers between those inputs.. however in my actual coding i did this with a function.
has school even started yet? no its not homework. im teaching myself C++.. – Sean Holt 1 min ago edit
No im just trying to figure a way of having the computer solve for x/y of an input value if x and y are between specified values in a function
It looks like you think that C++ is going to solve equations for you. It won't. C++ is an imperative style language that is based around the concept of you telling it exactly what to do.
You will have to figure out how to solve for x and y so that you can make an algorithm. This algorithm is then what you make your program from.
There exists other languages in which you can in a sense describe what you want and have the compiler or runtime figure out how to get it for you. C++ is not one of them.
Different ways to solve your particular problem would be to set up an equation system and solving that. Or do brute force approach and iterate through the values of x and y in order to find out which values match.
It looks like you have a 'mathematical' problem here: a couple of values constrained by equations, and you want 'the computer' to find all possible values that fit into the constraints (equations). Am I right?
While some computer programs can certainly do that, the C++ language is not designed for this purpose. The role of the C++ is to give you a way of giving instructions to the processor, like "store this value in memory" or "add these two numbers". But there is no way of saying "solve this mathematical problem".
What you need is some equation solver. But I am not familiar with any. There are tools like Matlab or Mathematica. But I do not think they are free.
If you want to solve the math problem algorithmically, here is a brute force idea in pseudocode:
Input a number.
for each value x between 30 and 50
for each value y between 60 and 90
if x+y equals the number
print x and y
Now you can take a good book or tutorial and code in C++. Look for the for and if keywords (algorithmic concepts of iteration and selection) in your teaching material. Have fun!
This case can be solved trivially by interval arithmetic. C++ code that solves your "sum of two interval-constrained variables problem" is given below.
int min_x = 30, max_x = 50;
int min_y = 60, max_y = 90;
// solutions exist in this interval
int min_z = min_x + min_y, max_z = max_x + max_y;
cin >> input;
// solutions possible?
if (input >= min_z && input <= max_z)
{
// determine solution interval for x (y is dependent)
cout
<< "Solution:\n"
<< "x in [" << min(max( input - max_y , min_x),max_x)
<< ";" << min(max( input - min_y , min_x),max_x) << "], "
<< "y = " << input << " - x" << endl;
}
else
{
cout << "No solution." << endl;
}
Computers are "basically stupid" and if they do smart things it is the software.
Using a general purpose programming language like C++ requires you (or at least
the libraries you eventually use) to be very specific on how exactly to solve
a problem based on the simple arithmetic means of the bare computer.
Although the programming language won't magically and somehow do things
for you, algorithms exist to solve many mathematical standard problems such
as e.g. systems of equations. Numerical Recipes in C++ covers a variety of
algorithms and their C++ implementations.