Complex numbers arithmetic goes wrong [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Right now I am trying to implement the formula for the probabilities of a Poisson binomial distribution.
The formula is the last one in that section, with complex exponentials inside them:
I have a very simple code that should do it, but it is outputting wrong probabilities.
#include <iostream>
#include <complex>
#include <cmath>
using namespace std;
int main(int argc, char const *argv[]) {
int N=5; //number of coins
double probabilities[N]={0.1,0.1,0.1,0.1,0.1}; //probabilities of coin landing head
double distr[N+1];
for (int j=0; j<N+1;j++){
complex<double> temp1=0.0 + 0.0i;
for (int k=0; k<N+1;k++){
for(int l=0;l<N+1;l++){
complex<double> temp2=1.0 + 0.0i;
for (int m=0;m<N;m++){
temp2=temp2*(1.0+0.0i+(exp(l*2*M_PI*1.0i/(double(N)+1.0))-1.0+0.0i)*probabilities[m]);
}
temp2=temp2*exp(l*k*2*M_PI*1.0i/(double(N)+1.0));
temp1=temp1+temp2/(double(N)+1.0);
}
}
distr[j]=real(temp1);
}
for (int i=0;i<N+1;i++){
cout<< distr[i] << ' ';
}
The output of this code is [1,1,1,1,1,1], which is definitely not correct. I am thinking that maybe I have not been working correctly with complex numbers, but I do not see where I did something wrong. It is frustrating that such a simple program does not work :(.

From the code it is clear that temp1 does not depend on j, hence you get the same numbers, the sum over k. After you remove the outer loop over j and write distr[k] = real(temp1); and fix the sign in exp(l*k*...), you'll get the expected result:
0.59049 0.32805 0.0729 0.0081 0.00045 1e-05
Full code with some simplifications:
int main() {
using namespace std::literals::complex_literals;
constexpr int N = 5;
const double probabilities[N] = {.1, .1, .1, .1, .1};
const auto c = std::exp(2i * M_PI / (N + 1.));
double distr[N + 1];
for (int k = 0; k <= N; ++k) {
auto sum = std::complex<double>(0);
for(int l = 0; l <= N; ++l) {
auto prod = std::complex<double>(1);
for (int m = 0; m < N; ++m)
prod *= 1. + (std::pow(c, l) - 1.) * probabilities[m];
sum += prod * std::pow(c, -l * k) / (N + 1.);
}
distr[k] = std::real(sum);
}
for (auto d : distr)
std::cout << d << ' ';
}

Related

Overflow in C++

So..
Here is the code:
#include <iostream>
#include <limits>
#include <math.h>
using namespace std;
int main()
{
unsigned long long i,y,n,x=45;
unsigned long long factorial = 1;
for(n = 0; n <= 5; n++)
{
y = (pow(-1,n)*pow(x,2*n)) / factorial;
cout << "COS IS " << y << endl;
}
for(int i = 1; i <=n; i++)
{
factorial *= 2*i;
}
}
I get an overflow but I really don't know why. I use unsigned long long just to make sure that I on't get but.. I still get it. Even limited to small numbers. I tried to implement this:
https://en.wikibooks.org/wiki/Trigonometry/Power_Series_for_Cosine_and_Sine
But I really can't do it because of the overflow. Do you have any ideea on what can I do ? I am newbie in programming so, take it easy on me :D
There are many issues.
you use integer types when you should use floating point types
you use unsigned types for signed calculations
you don't use radians but degrees (45° ≈ 0.78539 radians)
you don't calculate the factorial in the loop, it is always 1, you only calculate it at the end of the loop but then it's too late, and your calculation of the factorial is wrong anyway.
the algorithm is wrong, it just doesn't do what Maclaurin's therorem says, you need to sum up the terms, but you just print the terms.
You probably want this:
#include <iostream>
#include <cmath>
using namespace std;
long factorial(int n)
{
long result = 1;
for (int i = 1; i <= n; i++)
result *= i;
return result;
}
int main()
{
double x = 0.785398163397448309616; //PI/4 expectd result COS(PI/4) = 0.7071067
double mycosinus = 0;
for (int n = 0; n <= 5; n++)
{
mycosinus += (pow(-1, n) * pow(x, 2 * n)) / factorial(2*n);
cout << "COS IS " << mycosinus << endl;
}
}
This is your wrong algorithm for calculating the factorial of 5:
int main()
{
int n = 5;
int factorial = 1;
for (int i = 1; i <= n; i++)
{
factorial *= 2 * i;
}
cout << "factorial 5 = " << factorial << endl;
}
The calculated value is 3840 instead of 120. I let you find out what's wrong yourself.
For performing this sort of maths you need to use a floating point like float or double not integral types like long, int or long long, given that sin and cos can both return negative numbers you shouldn't be using unsigned either.

Can I find quadratic function when Im being given x and y values? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I was doing an algorithm where Im given x and y solution, and I need to find if possible, quadratic formula for that solutions.
What I actually mean is:
If Im given output:
f(1) = 1
f(2) = 5
f(3) = 13
f(4) = 25
So, the function should return 1,5,13,25
Function that gives that output is: 2x^2-2x+1, but how do I get that?
If your y-values are precise, you can solve system of linear equations
a*x1^2 + b*x1 + c = y1
a*x2^2 + b*x2 + c = y2
a*x3^2 + b*x3 + c = y3
substitute known values for three points and find unknowns coefficients a,b,c
If values are approximate, use least squares method (more precise - polynomial least squares) with all points
This is piece of code for least sqaure analysis. It is written for newmat matrix library. Because i don't use it right now so i am too lazy to rewrite it into armadillo library i am currently using. Just to avoid mistakes newmat starts with vector/matrix indexes from 1 instead of 0.
void polynomial_approx( const vector<double>& x, const vector<double>& fx, vector<double>& coeff, int pd)
{
// x - input values of independent variable
// fx - input values of dependent variable
// coeff - output vector with polynomial coeffiecients
// pd - polynomial degree
if ( x.size() < pd ){
cerr << "Not enough data for such high polynomial degree." << endl;
};
coeff.clear();
Matrix A(x.size(), pd + 1);
Matrix D(pd+1,pd+1);
ColumnVector y(fx.size());
ColumnVector dx;
// converting vector from c++ type to newmat vector
for (unsigned int i = 0; i < fx.size(); i++)
y(i+1) = fx[i];
// creating the design matrix
for (unsigned int i = 1; i <= x.size();i++ ){
for (unsigned int j = 1; j<= pd+1;j++ ){
A(i,j) = pow(x[i],j-1);
}
}
// compute the unknown coefficients
dx = (A.t() * A ).i() * A.t() * y;
for (unsigned int i = 1; i<= dx.Ncols(); i++)
coeff.push_back( dx(i) );
/* reconstruction of polynomial */
vector<double> recon (x.size(), 0.0 );
for ( unsigned int i = 0; i < x.size() ; i++){
for ( unsigned int j = 0; j< coeff.size(); j++){
recon[i] += coeff[j]*pow( x[i], (double) j );
}
}
}

calculating numerical integral in c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to write a function that can calculate me inetegral e^(cos x) on range (a,b)
double integral(double(*f)(double x), double a, double b, int n) {
double step = (b - a) / n; // width of each small rectangle
double area = 0.0; // signed area
for (int i = 0; i < n; i ++) {
area += f(a + (i + 0.5) * step) * step; // sum up each small rectangle
}
return area;
}
This is what I have found but I`m new in c++ and I can't work with pointers
if there is another way please help me.
That function you found allows you to integrate any function you want, and that funcion is the first parameter of the integral method. You can just remove the first argument ('double(*f)(double x)' ), that is because the function you want to integrate is known ( e^cos(x)), so you don't need to give it as an argument. Then, in the for loop, you just replace de f function for e^cos(x). The method will look like this:
double integral(double a, double b, int n){
double step = (b - a) / n; // width of each small rectangle
double area = 0.0; // signed area
for (int i = 0; i < n; i ++) {
area += exp(cos(a + (i + 0.5) * step)) * step; // sum up each small rectangle
}
return area;
}
#include <functional>
template<typename T>
T integral(const std::function<T(T)>& f, T a, T b, int n) {
auto step = (b - a) / n; // width of each small rectangle
auto area = static_cast<T>(0); // signed area
for (auto i = 0; i < n; i++)
{
// sum up each small rectangle
area += f(a + (i + static_cast<T>( 0.5)) * step) * step;
}
return area;
}
int main()
{
std::function<float(float)> f_sine = [](float in) { return sin(in); };
auto two = integral(f_sine, 0.0f, 3.14f, 20);
return 0;
}
That will be $3.50

Wrong logic in approximating e^1 :( [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I've written code using class object to calculate the value of e^1 by approximation using the summation of series given below, but seems like i can't get the logic to work properly.I tried running it to 5 terms for approximation but my answer was 1.2 only where it should be around 2.7038...
e^1 is given by the series 1 + 1/1! + 1/2! + 1/3! ...
#include <iostream>
#include <stdlib.h>
using namespace std;
class factorial
{
public:
double loopfactorial ( double y)
{
double value;
for (int a=0; a<=y; a++)
{
value=1;
value = value*a;
}
return value;
}
};
int main()
{
factorial calcu;
int x;
double sum;
cout<<"Enter the number of terms to approximate exponent:"<<endl;
cin>>x;
for (int y=1; y<=x-1; y++)
{
int n = calcu.loopfactorial(y);
sum=1.0;
sum = sum + 1/n;
}
cout<<"The value of e is "<<sum<<endl;
return 0;
}
For reference and the benefit of future readers, here's the "correct" code:
#include <iostream>
#include <cstdlib>
int main()
{
unsigned int terms;
if (!(std::cout << "Number of terms: " && std::cin >> terms))
{
std::cout << "Error, I did not understand you.\n";
return EXIT_FAILURE;
}
double e = terms > 0 ? 1.0 : 0.0, term = 1.0;
for (unsigned int n = 1; n < terms; ++n)
{
term /= n;
e += term; // this is "e += 1/n!"
}
std::cout << "e is approximately " << e << "\n";
}
(The code can be trivially extended to compute ex for any x.)
You should move the variable initializations out of the loops - you're resetting them over and over.
Side note: it's rather pointless to put loopfactorial in a class.
I found three problems with your code, both are similar to each other
1. in loopfactorial(), value=1 should be defined before the loop body
2. in main(), sum=1.0 should be defined before the loop body
3. in loopfactorial(), loop variable a should have been initialized with either 1 or 2 instead of 0.
Try moving your initial values outside the loop:
#include <iostream>
#include <stdlib.h>
using namespace std;
class factorial
{
public:
double loopfactorial ( double y)
{
double value;
// MOVED INITIAL VALUE HERE
value=1;
for (int a=1; a<=y; a++)
{
value = value*a;
}
return value;
}
};
int main()
{
factorial calcu;
int x;
double sum;
cout<<"Enter the number of terms to approximate exponent:"<<endl;
cin>>x;
// MOVED INITIAL VALUE HERE
sum=1.0;
for (int y=1; y<=x-1; y++)
{
int n = calcu.loopfactorial(y);
sum = sum + 1/n;
}
cout<<"The value of e is "<<sum<<endl;
return 0;
}

Audio Processing C++ - FFT

I'm probably going to ask this incorrectly and make myself look very stupid but here goes:
I'm trying to do some audio manipulate and processing on a .wav file. Now, I am able to read all of the data (including the header) but need the data to be in frequency, and, in order to this I need to use an FFT.
I searched the internet high and low and found one, and the example was taken out of the "Numerical Recipes in C" book, however, I amended it to use vectors instead of arrays. Ok so here's the problem:
I have been given (as an example to use) a series of numbers and a sampling rate:
X = {50, 206, -100, -65, -50, -6, 100, -135}
Sampling Rate : 8000
Number of Samples: 8
And should therefore answer this:
0Hz A=0 D=1.57079633
1000Hz A=50 D=1.57079633
2000HZ A=100 D=0
3000HZ A=100 D=0
4000HZ A=0 D=3.14159265
The code that I re-wrote compiles, however, when trying to input these numbers into the equation (function) I get a Segmentation fault.. Is there something wrong with my code, or is the sampling rate too high? (The algorithm doesn't segment when using a much, much smaller sampling rate). Here is the code:
#include <iostream>
#include <math.h>
#include <vector>
using namespace std;
#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr;
#define pi 3.14159
void ComplexFFT(vector<float> &realData, vector<float> &actualData, unsigned long sample_num, unsigned int sample_rate, int sign)
{
unsigned long n, mmax, m, j, istep, i;
double wtemp,wr,wpr,wpi,wi,theta,tempr,tempi;
// CHECK TO SEE IF VECTOR IS EMPTY;
actualData.resize(2*sample_rate, 0);
for(n=0; (n < sample_rate); n++)
{
if(n < sample_num)
{
actualData[2*n] = realData[n];
}else{
actualData[2*n] = 0;
actualData[2*n+1] = 0;
}
}
// Binary Inversion
n = sample_rate << 1;
j = 0;
for(i=0; (i< n /2); i+=2)
{
if(j > i)
{
SWAP(actualData[j], actualData[i]);
SWAP(actualData[j+1], actualData[i+1]);
if((j/2)<(n/4))
{
SWAP(actualData[(n-(i+2))], actualData[(n-(j+2))]);
SWAP(actualData[(n-(i+2))+1], actualData[(n-(j+2))+1]);
}
}
m = n >> 1;
while (m >= 2 && j >= m) {
j -= m;
m >>= 1;
}
j += m;
}
mmax=2;
while(n > mmax) {
istep = mmax << 1;
theta = sign * (2*pi/mmax);
wtemp = sin(0.5*theta);
wpr = -2.0*wtemp*wtemp;
wpi = sin(theta);
wr = 1.0;
wi = 0.0;
for(m=1; (m < mmax); m+=2) {
for(i=m; (i <= n); i += istep)
{
j = i*mmax;
tempr = wr*actualData[j-1]-wi*actualData[j];
tempi = wr*actualData[j]+wi*actualData[j-1];
actualData[j-1] = actualData[i-1] - tempr;
actualData[j] = actualData[i]-tempi;
actualData[i-1] += tempr;
actualData[i] += tempi;
}
wr = (wtemp=wr)*wpr-wi*wpi+wr;
wi = wi*wpr+wtemp*wpi+wi;
}
mmax = istep;
}
// determine if the fundamental frequency
int fundemental_frequency = 0;
for(i=2; (i <= sample_rate); i+=2)
{
if((pow(actualData[i], 2)+pow(actualData[i+1], 2)) > pow(actualData[fundemental_frequency], 2)+pow(actualData[fundemental_frequency+1], 2)) {
fundemental_frequency = i;
}
}
}
int main(int argc, char *argv[]) {
vector<float> numbers;
vector<float> realNumbers;
numbers.push_back(50);
numbers.push_back(206);
numbers.push_back(-100);
numbers.push_back(-65);
numbers.push_back(-50);
numbers.push_back(-6);
numbers.push_back(100);
numbers.push_back(-135);
ComplexFFT(numbers, realNumbers, 8, 8000, 0);
for(int i=0; (i < realNumbers.size()); i++)
{
cout << realNumbers[i] << "\n";
}
}
The other thing, (I know this sounds stupid) but I don't really know what is expected of the
"int sign" That is being passed through the ComplexFFT function, this is where I could be going wrong.
Does anyone have any suggestions or solutions to this problem?
Thank you :)
I think the problem lies in errors in how you translated the algorithm.
Did you mean to initialize j to 1 rather than 0?
for(i = 0; (i < n/2); i += 2) should probably be for (i = 1; i < n; i += 2).
Your SWAPs should probably be
SWAP(actualData[j - 1], actualData[i - 1]);
SWAP(actualData[j], actualData[i]);
What are the following SWAPs for? I don't think they're needed.
if((j/2)<(n/4))
{
SWAP(actualData[(n-(i+2))], actualData[(n-(j+2))]);
SWAP(actualData[(n-(i+2))+1], actualData[(n-(j+2))+1]);
}
The j >= m in while (m >= 2 && j >= m) should probably be j > m if you intended to do bit reversal.
In the code implementing the Danielson-Lanczos section, are you sure j = i*mmax; was not supposed to be an addition, i.e. j = i + mmax;?
Apart from that, there are a lot of things you can do to simplify your code.
Using your SWAP macro should be discouraged when you can just use std::swap... I was going to suggest std::swap_ranges, but then I realized you only need to swap the real parts, since your data is all reals (your time-series imaginary parts are all 0):
std::swap(actualData[j - 1], actualData[i - 1]);
You can simplify the entire thing using std::complex, too.
I reckon its down to the re-sizing of your vector.
One possibility: Maybe re-sizing will create temp objects on the stack before moving them back to heap i think.
The FFT in Numerical Recipes in C uses the Cooley-Tukey Algorithm, so in answer to your question at the end, the int sign being passed allows the same routine to be used to compute both the forward (sign=-1) and inverse (sign=1) FFT. This seems to be consistent with the way you are using sign when you define theta = sign * (2*pi/mmax).