C/C++ Goertzel algorithm with complex output or magnitude+phase? - c++

Does someone know where i can get code or a library to perform the Goertzel algorithm with a complex output?
(or any other 1-bin-DFT algorithm?)

The following is code that I wrote do this, some several years ago. Feel free to use it as you wish, with appropriate attribution.
goertzelfilter.h
/* goertzelfilter.h
*/
#ifndef GOERTZELFILTER_H_
#define GOERTZELFILTER_H_
#include <complex.h>
typedef struct goertzelfilterstruct {
double coeff ;
double sine ;
double cosine ;
} GoertzelFilter;
GoertzelFilter goertzelSetup( double normalizedfreq );
double complex goertzelFilterC( double *sample, int nsamples, GoertzelFilter *g );
#endif
goerzelfilter.c
/* goertzelfilter.c
*/
#include <math.h>
#include <stdlib.h>
#include <complex.h>
#include "goertzelfilter.h"
GoertzelFilter goertzelSetup( double normalizedfreq )
{
double w = 2*M_PI*normalizedfreq;
double wr, wi;
GoertzelFilter g;
wr = cos(w);
wi = sin(w);
g.coeff = 2 * wr;
g.cosine = wr;
g.sine = wi;
return g;
}
double complex goertzelFilterC( double *samples, int nsamples, GoertzelFilter *g )
{
double sprev = 0.0;
double sprev2 = 0.0;
double s, imag, real;
int n;
for (n=0; n<nsamples; n++ ) {
s = samples[n] + g->coeff * sprev - sprev2;
sprev2 = sprev;
sprev = s;
}
real = sprev*g->cosine - sprev2;
imag = -sprev*g->sine;
return real + I*imag;
}
And for a test, you can try this,
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include "goertzelfilter.h"
#define LEN(a) (sizeof(a)/sizeof(a[0]) )
int main() {
// This will hold our input and output data
double data[1024] = { 0. };
double complex filtered[1024] = { 0. };
// This will hold the filter constants
GoertzelFilter g = { 0. };
int n;
int nwindow = 16;
double f = 4./LEN(data) ;
// Generate data with noise
for ( n = 0 ; n < LEN(data) ; n++ ) {
data[n] = sin( n * (2.*M_PI) * f ) + 0.5*((float)rand()/RAND_MAX - 0.5);
}
// Set up the filter constants, note that we choose a frequency
g = goertzelSetup( f );
// Filter the data using a sliding window
for( n = 0 ; n < LEN(data)-nwindow ; n++ ) {
filtered[n+nwindow/2] = goertzelFilterC( &data[n], nwindow, &g )/nwindow;
}
// Print the real Valued Data (1st column) and complex valued Goertzel output
for( n = 0 ; n < LEN(data); n++ ) {
printf( "%g %g %g\n", data[n], creal(filtered[n]), cimag(filtered[n]) );
}
}
And here is a graph showing the input and output from the test code:

Related

Passing Arrays through Fuctions - "Error: Cannot Convert 'float**' to 'float*' for argument '1'"

Long time Reader, First time Asker.
So I'm working on a coding project of which the long term goal is to make a solar system simulator. The idea is that that it whips up a randomized solar system with a few rules like 'at formation the first planet after the frostline has to be the largest gas giant' etc, and calculates the orbits to check for stability.
Obviously it's not done yet, I'm having some trouble with using the arrays in the subroutines. I know that you can't directly take arrays in and out of functions, but you can take pointers to said arrays in and out of functions if you do it right.
I apparently have not done it right below. I've tried to comment and make the code as readable as possible, here it is.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <tuple>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <complex>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <algorithm>
//#include "mpi.h"
using namespace std;
double MyRandom(){
//////////////////////////
//Random Number Generator
//Returns number between 0-99
//////////////////////////
double y = 0;
unsigned seed = time(0);
srand(seed);
uint64_t x = rand();
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
x = (1070739 * x) % 2199023255530;
y = x / 21990232555.31 ;
return y;
}
////////////////////////
///////////////////////
tuple< char& , float& , float& , float& , int& > Star(){
////////////////////////////
//Star will generate a Star
//Randomly or User Selected
//Class, Luminosity, Probability, Radius, Mass, Temperature
//Stars always take up 99% of the mass of the system.
///////////////////////////
char Class;
string Choice;
float L, R, M;
int T;
tuple< char& , float& , float& , float& , int& > star( Class = 'i', L = 1 , R = 1 , M = 1 , T = 3000) ;
cout << "Select Star Class (OBAFGKM) or Select R for Random: ";
cin >> Choice;
if ( Choice == "R" ) {
double y;
y = MyRandom();
if (y <= 0.003) Class = 'O';
if ((y > 0.003) && (y <= 0.133)) Class = 'B';
if ((y > 0.133) && (y <= 0.733)) Class = 'A';
if ((y > 0.733) && (y <= 3.733)) Class = 'F';
if ((y > 3.733) && (y <= 11.333)) Class = 'G';
if ((y > 11.333) && (y <= 23.433)) Class = 'K';
else Class = 'M';
}
if (Class == 'O') {
L = 30000;
R = 0.0307;
M = 16;
T = 30000;
}
if (Class == 'B') {
L = 15000;
R = 0.0195;
M = 9;
T = 20000;
}
if (Class == 'A') {
L = 15;
R = 0.00744;
M = 1.7;
T = 8700;
}
if (Class == 'F') {
L = 3.25;
R = 0.00488;
M = 1.2;
T = 6750;
}
if (Class == 'G') {
L = 1;
R = 0.00465;
M = 1;
T = 5700;
}
if (Class == 'K') {
L = 0.34;
R = 0.00356;
M = 0.62;
T = 4450;
}
if (Class == 'M') {
L = 0.08;
R = 0.00326;
M = 0.26;
T = 3000;
}
return star;
}
////////////
////////////
float* Planet( float &L, float &R, float &M, int &T, int &n){
///////////////////////////
//Planet generates the Planets
//Random 1 - 10, Random distribution 0.06 - 6 JAU unless specified by User
//Frost line Calculated, First Planet after Frost line is the Jupiter
//The Jupiter will have the most mass of all Jovian worlds
//Otherwise divided into Jovian and Terrestrial Worlds, Random Masses within groups
//Also calculates if a planet is in the Habitable Zone
////////////////////////////
float frostline, innerCHZ, outerCHZ;
float a = 0.06; // a - albedo
float m = M / 100; //Mass of the Jupiter always 1/100th mass of the Star.
float sys[n];
float* system[n][5] = {{0}};
for (int i = 0 ; i < n ; i++){
sys[i] = MyRandom()/10 * 3; //Distances in terms of Sol AU
}
sort(sys, sys + n );
for (int i = 0 ; i < n ; i++){
system[i][0] = &sys[i];
system[i][1] = 0; //system[i][0] is x, system[i][1] is y
}
frostline = (0.6 * T / 150) * (0.6 * T/150) * R / sqrt(1 - a);
innerCHZ = sqrt(L / 1.1);
outerCHZ = sqrt(L / 0.53);
for (int i = 0 ; i < n ; i++){
if (system[i][0] <= &frostline) {
float tmass = m * 0.0003 * MyRandom();
system[i][2] = &tmass ; //system[i][2] is mass, [3] is marker for the Jupter
system[i][3] = 0 ;
}
if ((system[i][0] >= &frostline) && (system[i-1][0] < &frostline)){
system[i][2] = &m ;
float J = 1;
system[i][3] = &J ;
}
if ((system[i][0] >= &frostline) && (system[i-1][0] >= &frostline)) {
float jmass = m * 0.01 * MyRandom();
system[i][2] = &jmass ;
system[i][3] = 0 ;
}
if ((system[i][0] >= &innerCHZ) && (system[i][0] <= &outerCHZ)){
float H = 1;
system[i][4] = &H;
}
else system[i][4] = 0; //[4] is habitable marker
}
return system[n][5];
}
////////////
////////////
float* Time( float *system , int n){
///////////////////////////
//Time advances the solar system.
//Plots the Orbits
//Uses MPI to spread it's calculations.
///////////////////////////
return system;
}
////////////
////////////
void FinalCheck( float system){
///////////////////////////
//Final Checks
//Reports if a Planet spent the whole Time in the Habitable Zone
///////////////////////////
/*for (int i = 0 ; i < row ; i++){
if (system[i][4] == 1.0) {
cout << "Planet " << i << " in this system is Habitable." ;
}
// The Habitable stat only means liquid water can exist on the surface
// Add pi if planet enters habitable zone, minus 1 if it leaves.
// If planet was habitable but left, assuming all life was destroyed
}
*/
}
////////////
int main(){
char Class;
int T;
float L, R, M;
tuple< char , float , float , float , int > star( Class , L , R , M , T );
star = Star();
int n = MyRandom()/10 + 1;
float * system[n][5] = {{0}};
float system1[n][5] = {{0}};
system[n][5] = Planet( L , R , M, T, n);
for (int i = 0 ; i < 100 ; i++) {
system1[n][5] = Time( *system, n );
system[n][5] = &system1[n][5];
}
FinalCheck( *system[n][5]);
///////////////////////////
//Report cleans everything up and gives the results
//Shows the plot, lists the Planets
//Reports the Positions and Masses of all Planets
//Reports which was the Jupiter and which if any were Habitable
//////////////////////////
return 0;
}
The problem is when I run a compiler over this line 227 gets flagged -
system1[n][5] = Time( *system, n );
With the following error:
error: cannot convert 'float**' to 'float*' for argument '1' to 'float* Time(float*, int)
I get that this means that the compiler things I'm trying to equate a pointer-to-a-pointer with a pointer, but I'm not sure how it arrived at that conclusion or how to fix it. I'd appreciate help with this, especially the second part. I also would love to hear anything about passing arrays through subroutines as apparently I'm not doing it right, or at least not well.
Update 1 : - Got the short-term fix in and the compiler makes it through but gives a segmentation fault (core dumped) error when I try to run it. Looks like I have some reading and updates to do though with the namespace, the pointers, and possibly changing the arrays into vectors instead. Feels like if I concentrate on those first it might fix the segmentation error.
Your variable system is declared as
float * system[n][5] = {{0}};
which is a pointer to a 2D array (which will decay to float*** when passed to a function).
Your Time function is declared as
float* Time( float *system , int n);
where the 1st argument needs to be a float*.
That means this call
system1[n][5] = Time( *system, n );
should actually be something like
system1[n][5] = Time( **system, n );
That being said, there are a number of issues in your code.
To start off, don't do using namespace std;.
Also, this line float sys[n]; is not allowed. You can't have variable length arrays in c++.
float* system[n][5]
system here is a 2D array of float*s, not floats.
So, in other words, system decays to float***, *system decays to float**, **system decays to float*, and ***system decays to float.
So, the compiler is correct. You're passing what decays to a float** to Time() which expects a float*.
You're going to have to reconfigure your code to pass the right thing, whatever that is.
Side note: please be advised that the way you're creating arrays isn't valid C++ and may cause issues later.

How to use properly FFTW in C++ with vectors?

I am a very beginner in C++ and for my internship I have to use the fftw library to get the fourier transform of a signal.
Actually, at first, I use python for my programm and then I tried to translate it into C++. However, it doesn't work and I really cannot understand why... I am not really used to pointers and stuff like that so maybe that is the problem. First, I would like to know why programms (the one in python and the in C++) do not give the same results ?
Moreover, I would be very grateful if someone could explain me how to use FFTW with vectors ? I would like to better understand things. Thank you very much :)
The python Code
import numpy as np
import matplotlib.pyplot as plt
from math import cos, sin, sqrt, pi, exp as cos, sin, sqrt, pi, exp
#parameters (suprathresold case)\
eps = 0.05
f = 0.215
mu = 1.1
D = 0.001
DeltaT = 0.001
period = int(1.0 / f / DeltaT)
num_periods_4_transient = 10
num_periods_4_spectrum = 100
#timewindow = 2 * period * DeltaT #quite long to be independant of the transient
l_transient = num_periods_4_transient * period
l_measure = num_periods_4_spectrum * period
#num_points = int(timewindow/DeltaT)
N = 100 # number of realization (number of neurons) should be at the end 10^8
DeltaT_ratio = 100
#signal that modulates the firing rate
#s = [sin(2*3.14*f*t) for t in T]
ts_transient = np.arange(l_transient)*DeltaT
ts_measure = np.arange(l_measure)*DeltaT
s = np.sin(2.0 * np.pi * f * ts_transient)
#Euler's method with FFT
v0 = np.zeros(N)
v = np.zeros((l_transient,N))
samples = np.random.normal(0, 1, (l_transient,N))
DeltaF = 1.0 / (l_measure * DeltaT)
#print "running transient..."
for i in range(1,l_transient):
v[i,:] = v[i-1,:] + DeltaT *(-v[i-1,:]+ mu + eps*s[i-1])+ sqrt(2*D*DeltaT)*samples[i,:]
mask_sp = v[i,:] > 1
v[i, mask_sp ] = 0
v0 = v[-1,:]
v = np.zeros((l_measure,N))
v[0,:] = v0
s = np.sin(2.0 * np.pi * f * ts_measure)
samples = np.random.normal(0, 1, (l_measure,N))
l_compteur = l_measure // DeltaT_ratio + 1
compteur=np.zeros((l_compteur, N))
DeltaT_prime = DeltaT * DeltaT_ratio
#print l_measure,l_measure // DeltaT_ratio
#print "running for measure..."
for i in range(1,l_measure):
v[i,:] = v[i-1,:] + DeltaT *(-v[i-1,:]+ mu + eps*s[i-1])+ sqrt(2*D*DeltaT)*samples[i,:]
mask_sp = v[i,:] > 1
compteur[ int(i / DeltaT_ratio), mask_sp ] = 1.0 / DeltaT_prime
v[i, mask_sp ] = 0
l_freq = int(l_compteur / 2) + 1
spectrum_matrix = np.abs(np.fft.rfft(compteur,axis=0)*DeltaT_prime)**2
powerspectra = np.mean(spectrum_matrix,axis=1)
powerspectra /= (l_measure*DeltaT)
powerspectra[0] = 0.0
plt.plot(np.arange(l_freq)*DeltaF, powerspectra )
plt.show()
The C++ Code
#include <iostream>
#include <cmath>
#include <complex>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <fftw3.h>
#define PI 3.1415926535897932384626433832795
#include <vector>
using namespace std;
double s(double x, double );
double AWGN_generator(void);
std::string double2str(const double x)
{
stringstream sss;
sss<<x;
return sss.str();
}
int main()
{
// srand (time(NULL));
//parameters
double eps = 0.05;
double f_1 = 0.215 ;
//double f_2 = 0.33;
double mu = 1.1 ;
double D = 0.001 ;
double deltaT = 0.001;
long period = 1.0 / f_1 / deltaT;
int N = 1000; //# number of realization (number of neurons) should be at the end 10^8
long DeltaT_ratio = 100;
double DeltaT_prime = DeltaT_ratio*deltaT;
int num_periods_4_transient = 10;
int num_periods_4_spectrum = 20;
long l_transient = num_periods_4_transient * period;
long l_measure = num_periods_4_spectrum * period;
long l_compteur = l_measure / DeltaT_ratio + 1 ;
long l_freq = int(l_compteur / 2) + 1;
double deltaf = 1.0 / (l_compteur * DeltaT_prime);
vector<double> powerspectrum(l_freq,0);
cout<<l_measure<<l_measure / DeltaT_ratio<<endl;
double a = 1.0;
ofstream m_out ;
string outfile = "/Users/Pierrot/powerspectrum_test.txt";
m_out.open(outfile.c_str());
vector< double > compteur(l_compteur,0);
std::vector< std::complex<double> > out(l_freq,0);
fftw_plan p;
p = fftw_plan_dft_r2c_1d(l_compteur, &compteur[0], reinterpret_cast<fftw_complex*>(&out[0]), FFTW_MEASURE);
//cout<<"test1"<<endl;
// Transient
vector< double > v(l_transient,0.0 );
vector<double> Time(l_transient, 0) ;
for (int i = 0 ; i < l_transient ; i++ )
{ Time[i] = deltaT*i ;
}
int pos_1 ;
for (pos_1 = 1 ; pos_1<l_transient ; pos_1 ++)
{
double t = Time[pos_1-1] ;
v[pos_1] = v[pos_1-1] + deltaT*(-v[pos_1-1]+ mu + eps*s(t, f_1)) + sqrt(2*D*deltaT)*AWGN_generator();
if (v[pos_1]>1)
{
v[pos_1]=0 ;
}
}
vector< double > v_bis(l_measure, v[l_transient-1]);
// v_bis[0]=v[l_transient-1];
for( int k=0; k<N ; k++)
{
//copy last value of transient in the new v
v_bis[0] = v_bis[l_measure-1];
double DeltaT_prime = deltaT * DeltaT_ratio ;
vector<double> Time_bis(l_measure) ;
for (int i = 0 ; i < l_measure ; i++ )
{ Time_bis[i] = deltaT*i ;
}
//cout<<"test2"<<endl;
for (int pos_1_bis = 1 ; pos_1_bis<l_measure ; pos_1_bis ++)
{
double t = Time_bis[pos_1_bis-1] ;
v_bis[pos_1_bis] = v_bis[pos_1_bis-1] + deltaT*(-v_bis[pos_1_bis-1]+ mu + eps*s(deltaT*(pos_1_bis-1), f_1)) + sqrt(2*D*deltaT)*AWGN_generator();
//cout<<v_bis[pos_1_bis]<<endl;
if (v_bis[pos_1_bis]>1)
{
v_bis[pos_1_bis]=0 ;
compteur[pos_1_bis/DeltaT_ratio] = 1.0/DeltaT_prime ;
// cout<<pos_1_bis/DeltaT_ratio<<endl;
}
}
fftw_execute(p);
for (long m(0);m<l_freq;m++)
{
powerspectrum[m] += (real( out[m] * conj(out[m]) ) * DeltaT_prime*DeltaT_prime) / (l_measure*deltaT*N);
}
}
//powerspectrum = powerspectrum *DeltaT_prime*DeltaT_prime/(l_measure*deltaT*N)
fftw_destroy_plan(p);
fftw_cleanup();
for (long m(1);m<l_freq;m++)
{
m_out<<deltaf*m <<"\t"<<powerspectrum[m]<<"\n";
}
m_out.close();
printf("ca a marche test.txt");
return 0;
}
double s(double x, double f)
{
return sin(2*PI*f*x);
}
double AWGN_generator()
{/* Generates additive white Gaussian Noise samples with zero mean and a standard
deviation of 1. */
double temp1;
double temp2;
double result;
int p;
p = 1;
while( p > 0 )
{
temp2 = ( rand() / ( (double)RAND_MAX ) ); /* rand() function generates an
integer between 0 and RAND_MAX,
which is defined in stdlib.h.
*/
if ( temp2 == 0 )
{// temp2 is >= (RAND_MAX / 2)
p = 1;
}// end if
else
{// temp2 is < (RAND_MAX / 2)
p = -1;
}// end else
}// end while()
temp1 = cos( ( 2.0 * (double)PI ) * rand() / ( (double)RAND_MAX ) );
result = sqrt( -2.0 * log( temp2 ) ) * temp1;
return result; // return the generated random sample to the caller
}
You are probably invoking undefined behaviour here
reinterpret_cast<fftw_complex*>(&out[0])
That section should be
std::vector<double> compteur(l_compteur);
std::vector<fftw_complex> out(l_freq);
fftw_plan p = fftw_plan_dft_r2c_1d(compteur.size(), compteur.data(), out.data(), FFTW_MEASURE);
This would be much easier to follow if you broke it up into functions, start by extracting each block of calculation that stands on it's own, but you can't go too far.
Other than that, you should avoid using namespace std;, consider using generators in <random>

Non-Linear Fit Using GSL

So I'm trying to modify some code I found here to fit a different function, but my slightly modified version fails to converge and I don't understand why.
The function I'm trying to find the least squared fit for is "A + lambdalog(t) + blog(t)^2. Here's the code
main.cpp
#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_multifit_nlin.h>
#include "expfit.c"
#define N 40 // All "N"s are 40
void print_state (size_t iter, gsl_multifit_fdfsolver * s);//The prototype of some function
int main (void){
const gsl_multifit_fdfsolver_type *T; //pointer to a newly allocated instance of a solver of type T
gsl_multifit_fdfsolver *s;
int status;
unsigned int i, iter = 0;
const size_t n = N; //N number of observations
const size_t p = 3;//3 parameters
gsl_matrix *covar = gsl_matrix_alloc (p, p); // creates a pxp gsl_matrix
double y[N], sigma[N]; //declares vector variables that will hold the noise data. They are "N" long
struct data d = { n, y, sigma}; //Populates struct d with variables n, y and sigma. Struct data is defined in expfit.c
gsl_multifit_function_fdf f;
double x_init[3] = { 0, -.1, -.1 }; //initial x values !These are initial guesses to the solution!
gsl_vector_view x = gsl_vector_view_array (x_init, p);//view arrays allow one to litterally view elements of a certain array without modifying or created a copy of the original array. Essentially a pointer to the original data.
const gsl_rng_type * type; // pointer to a new random number generator type. RNG type will be assigned later
gsl_rng * r; //Pointer to a new RNG
gsl_rng_env_setup();
type = gsl_rng_default; //Assigns random number generator type
r = gsl_rng_alloc (type); // Allocates memory for new RNG of type "type"
f.f = &logb_f;
f.df = &logb_df;
f.fdf = &logb_fdf;
f.n = n;
f.p = p;
f.params = &d;
for (i = 0; i < n; i++){// This is where the data is being generated
double t = i; // t is being redclared at each iteration for some reason wtf
if(t==0){//since log(0) is undefined, I said they equal 0 at t=0
y[i] = 2.0 -.5 * 0 - 0 + gsl_ran_gaussian (r, 0.1);
}else{
y[i] = 2.0 -.5 * log (t) - pow(log(t),2) + gsl_ran_gaussian (r, 0.1); //This is the noised up data
}
sigma[i] = .1; //not sure what this sigma does
printf ("data: %u %g %g\n", i, y[i], sigma[i]);//Printing out the data at each iteration
};
T = gsl_multifit_fdfsolver_lmsder; // Not sure what this is doing
s = gsl_multifit_fdfsolver_alloc (T, n, p);
gsl_multifit_fdfsolver_set (s, &f, &x.vector);
print_state (iter, s);
do{
iter++;
status = gsl_multifit_fdfsolver_iterate (s);
printf ("status = %s\n", gsl_strerror (status));
print_state (iter, s);
if (status)
break;
status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4);
}while (status == GSL_CONTINUE && iter < 500);
gsl_multifit_covar (s->J, 0.0, covar);
#define FIT(i) gsl_vector_get(s->x, i)
#define ERR(i) sqrt(gsl_matrix_get(covar,i,i))
{
double chi = gsl_blas_dnrm2(s->f);
double dof = n - p;
double c = GSL_MAX_DBL(1, chi / sqrt(dof));
printf("chisq/dof = %g\n", pow(chi, 2.0) / dof);
printf ("A = %.5f +/- %.5f\n", FIT(0), c*ERR(0));
printf ("lambda = %.5f +/- %.5f\n", FIT(1), c*ERR(1));
printf ("b = %.5f +/- %.5f\n", FIT(2), c*ERR(2));
}
printf ("status = %s\n", gsl_strerror (status));
gsl_multifit_fdfsolver_free (s);
gsl_matrix_free (covar);
gsl_rng_free (r);
return 0;
}
void print_state (size_t iter, gsl_multifit_fdfsolver * s){
printf ("iter: %3zu x = % 15.8f % 15.8f % 15.8f "
"|f(x)| = %g\n",
iter,
gsl_vector_get (s->x, 0),
gsl_vector_get (s->x, 1),
gsl_vector_get (s->x, 2),
gsl_blas_dnrm2 (s->f));
}
expfit.c
//
// expfit.c
// test
//
// Created by [] on 4/11/15.
// Copyright (c) 2015 []. All rights reserved.
//
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_multifit_nlin.h>
#include "expfit.h"
/* expfit.c -- model functions for exponential + background */
struct data {
size_t n;
double * y;
double * sigma;
};
int logb_f (const gsl_vector * x, void *data, gsl_vector * f){
size_t n = ((struct data *)data)->n;
double *y = ((struct data *)data)->y;
double *sigma = ((struct data *) data)->sigma;
double A = gsl_vector_get (x, 0);
double lambda = gsl_vector_get (x, 1);
double b = gsl_vector_get (x, 2);
double Yi;//will hold the value of the function to be stored into the vector set
double t;//time variable.
size_t i;//iterative variable
for (i = 0; i < n; i++){
/* Model Yi = A + lambda*log(i) + b*lambda*log(i)^2 */
t = i;
if(t==0){ //need if statement to bypass log(0) when t==0 since the value of log is undefined there
Yi = A + lambda * log(t) + b * pow(log(t),2);//function for t==0
}else{
Yi = A + lambda * log(t) + b * pow(log(t),2); // This is the function we used
}
gsl_vector_set (f, i, (Yi - y[i])/sigma[i]);
}
return GSL_SUCCESS;
}
int logb_df (const gsl_vector * x, void *data, gsl_matrix * J){
size_t n = ((struct data *)data)->n;
double *sigma = ((struct data *) data)->sigma;
//double A = gsl_vector_get (x, 0);
//double lambda = gsl_vector_get (x, 1);
//double b = gsl_vector_get(x,2);
size_t i;
for (i = 0; i < n; i++){
/* Jacobian matrix J(i,j) = dfi / dxj, */
/* where fi = (Yi - yi)/sigma[i], */
/* Yi = A + lambda*log(i) + b*log(i)^2 */
/* and the xj are the parameters (A,lambda,b) */
double t = i;
double s = sigma[i];
gsl_matrix_set (J, i, 0, 1/s);
gsl_matrix_set (J, i, 1, log(t)/s);
gsl_matrix_set (J, i, 2, pow(log(t),2)/s);
}
return GSL_SUCCESS;
}
int logb_fdf (const gsl_vector * x, void *data, gsl_vector * f, gsl_matrix * J){
logb_f (x, data, f);
logb_df (x, data, J);
return GSL_SUCCESS;
}
And here's the header file just incase you want it
//
// expfit.h
// test
//
// Created by [] on 4/11/15.
// Copyright (c) 2015 []. All rights reserved.
//
#ifndef __test__expfit__
#define __test__expfit__
#include <stdio.h>
#endif /* defined(__test__expfit__) */
When computing the fitting function, you consider the special case t=0 to avoid log(0), but the function values don't differ:
if(t==0){
Yi = A + lambda * log(t) + b * pow(log(t),2);//function for t==0
}else{
Yi = A + lambda * log(t) + b * pow(log(t),2); // This is the function we used
}
Furthermore, you don't consider this case when computing the derivatives.
So, I changed the function and the derivatives as follows:
int logb_f (const gsl_vector * x, void *data, gsl_vector * f){
size_t n = ((struct data *)data)->n;
double *y = ((struct data *)data)->y;
double *sigma = ((struct data *) data)->sigma;
double A = gsl_vector_get (x, 0);
double lambda = gsl_vector_get (x, 1);
double b = gsl_vector_get (x, 2);
double Yi;//will hold the value of the function to be stored into the vector set
double t;//time variable.
size_t i;//iterative variable
for (i = 0; i < n; i++){
/* Model Yi = A + lambda*log(i) + b*lambda*log(i)^2 */
t = i;
if(t==0){ //need if statement to bypass log(0) when t==0 since the value of log is undefined there
Yi = A ;
}else{
Yi = A + lambda * log(t) + b * pow(log(t),2); // This is the function we used
}
//Yi = A + lambda * log(t) + b * pow(log(t),2); // This is the function we used
gsl_vector_set (f, i, (Yi - y[i])/sigma[i]);
}
return GSL_SUCCESS;
}
int logb_df (const gsl_vector * x, void *data, gsl_matrix * J){
size_t n = ((struct data *)data)->n;
double *sigma = ((struct data *) data)->sigma;
//double A = gsl_vector_get (x, 0);
//double lambda = gsl_vector_get (x, 1);
//double b = gsl_vector_get(x,2);
size_t i;
for (i = 0; i < n; i++){
/* Jacobian matrix J(i,j) = dfi / dxj, */
/* where fi = (Yi - yi)/sigma[i], */
/* Yi = A + lambda*log(i) + b*log(i)^2 */
/* and the xj are the parameters (A,lambda,b) */
// d
double t = i;
double s = sigma[i];
if(i == 0)
{
gsl_matrix_set (J, i, 0, 0);
gsl_matrix_set (J, i, 1, 0);
gsl_matrix_set (J, i, 2, 0);
}
else
{
gsl_matrix_set (J, i, 0, 1/s);
gsl_matrix_set (J, i, 1, log(t)/s);
gsl_matrix_set (J, i, 2, pow(log(t),2)/s);
}
//Yi = A + lambda * log(t) + b * pow(log(t),2); // This is the function we used
}
return GSL_SUCCESS;
}
In this case the iteration converges:
iter: 0 x = 0.00000000 -0.10000000 -0.10000000 |f(x)| = 470.77
status = success
iter: 1 x = 2.08763815 -0.60282892 -0.97819822 |f(x)| = 5.5047
status = success
iter: 2 x = 2.08763815 -0.60282892 -0.97819822 |f(x)| = 5.5047
chisq/dof = 0.818964
A = 2.08764 +/- 0.08245
lambda = -0.60283 +/- 0.07702
b = -0.97820 +/- 0.01722
status = success
However, I recommend to verify the differentiability of the fit function for t -> 0.
If in doubt, you can also restrict the fit range in the above functions by only considering the values for t > 0:
for (i = 1; i < n; i++) ... instead of for (i = 0; i < n; i++) ...

Solving an equation with d&c method

I want to calculate value of x in this equation to 4 digits after the decimal with divide and conquer method.Values of p,q,r,s,t,u are input. How to do it in?
Time limits: 1 sec
Memory limits: 64 MB
float results[10000];
int n = 0;
for( float step = 0; i < 1; i+=0.00001 )
{
results[n] = callProblem( i );
}
some divide and conquer approach
float x = 0;
float diff = 1;//Startvalue
while( )
{
result = callProblem(x);
if( result > 0 )
{
x -= diff;
diff = diff/2;
result = callProblem(x);
}
else
{
x += diff;
diff = diff/2;
result = callProblem(x);
}
}
I have generalized the bisection method into an untested recursive multi-section method:
#include <math.h>
#include <stdio.h>
#include <time.h>
#define P 1.0
#define q 2.0
#define r 3.0
#define s 1.0
#define t 5.0
#define u -6.0
// number of sub-intervals in search interval
#define INTERVALS 10
// accuracy limit for recursion
#define EPSILON 1.0e-4
double f(double x) {
double y = P * exp(-x) + q*sin(x) + r*cos(x) + s*tan(x) + t*x*x + u;
return y;
}
// sign macro: -1 for val < 0, +1 for val > 0
#define SGN(val) ((0.0 < val) - (val < 0.0))
// return approximate x for function(x)==0.0
// "function" points to the function to be solved
double solve(double xMin, double xMax, double (*function)(double)) {
double arguments[INTERVALS + 1];
double values[INTERVALS + 1];
int prevSign;
int sign;
if (fabs(xMax - xMin) < EPSILON) {
// interval quite tight already
return (xMax + xMin) / 2.0;
}
// split the interval into sub-intervals
// evaluate the function for INTERVALS+1 equidistant points
// across our search interval
for (int i = 0; i <= INTERVALS; i++) {
double x = xMin + i*((xMax - xMin) / INTERVALS);
arguments[i] = x;
values[i] = function(x);
}
// look for adjacent intervals with opposite function value signs
// if f(Xi) and f(Xi+1) have different signs, the root must be
// between Xi and Xi+1
prevSign = SGN(values[0]);
for (int i = 1; i <= INTERVALS; i++) {
sign = SGN(values[i]);
if (sign * prevSign == -1) {
// different signs! There must be a solution
// Shrink search interval to the detected sub-interval
double x = solve(arguments[i - 1], arguments[i], function);
return x;
}
// remember sign for next round
prevSign = sign;
}
// no solution found: return not-a-number
return NAN;
}
int main(unsigned argc, char **argv) {
clock_t started = clock();
clock_t stopped;
double x = solve(0.0, 1.0, &f);
if (isnan(x)) {
printf("\nSorry! No solution found.\n");
} else {
printf("\nOK! Solution found at f(%f)=%f\n", x, f(x));
}
stopped = clock();
printf("\nElapsed: %gs", (stopped - started) / (double)CLOCKS_PER_SEC);
// wait for user input
getchar();
}

Perlin noise, blocky,c++

Okay first of all, I am trying to implement the Perlin noise algorithm, and I managed to achived something strange, and I can't find the solution. I am using matlab to visualize the results I have already checked this question:
"Blocky" Perlin noise
I am doing it from this website:
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
And another website which I can't find right now but I will update as soon as I can.
So here are some pictures about the problem:
This is the problem if increase zoom
http://i.stack.imgur.com/KkD7u.png
And here are the .cpp-s:
//perlin.cpp
#include "Perlin_H.h"
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <random>
using namespace std;
double Perlin::interp1(double a, double b, double x) {
double ft = x * 3.1415927;
double f = (1.0-cos(ft)) * 0.5;
//return (b-x > b-1/2) ? b-x : a+x;
return a * (1.0-f) + b * f;
}
double Perlin::smoothNoise(double x,double y) {
double corners = ( rand2(x-1, y-1)+rand2(x+1, y-1)+rand2(x-1, y+1)+rand2(x+1, y+1) ) / 16;
double sides = ( rand2(x-1, y) +rand2(x+1, y) +rand2(x, y-1) +rand2(x, y+1) ) / 8;
double center = rand2(x,y)/4;
return corners + sides +center;
}
double Perlin::lininterp1(double a,double b, double x) {
return a*(1-x) + b * x;
}
double Perlin::rand2(double x, double y) {
int n = (int)x + (int)y*57;
//n=pow((n<<13),n);
n=(n<<13)^n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
double Perlin::noise(double x, double y) {
double floorX = (double)floor(x);
double floorY = (double)floor(y);
double s,t,u,v;
s = smoothNoise(floorX,floorY);
t = smoothNoise(floorX+1,floorY);
u = smoothNoise(floorY,floorY+1);
v = smoothNoise(floorX+1,floorY+1);
double int1 = interp1(s,t,x-floorX);
double int2 = interp1(u,v,x-floorX);
return interp1(int1,int2,y-floorY);
}
//main.cpp
#include "Perlin_H.h"
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <fstream>;
using namespace std;
int main() {
const int h=64,w=64,octaves=2;
double p=1/1;
double zoom = 30;
Perlin perlin;
double map[h][w];
ofstream output;
output.open("map.txt");
for(int i = 0; i < h ; i++) {
for(int j = 0; j < w ; j++) {
map[i][j] = 0;
}
}
double freq = 2;
for(int i = 0; i < h ; i++) {
for(int j = 0; j < w ; j++) {
double getnoise = 0;
for(int a=0; a < octaves; a++) {
double freq = pow(2,a);
double amp = pow(p,a);
getnoise = perlin.noise((((double)i)*freq)/zoom-(a*10),
((((double)j))*freq)/zoom+(a*10))*amp;
int color = (int)((getnoise * 128.0) + 128.0);
if(color > 255) color = 255;
if(color < 0) color = 0;
map[i][j] = color;
}
output << map[i][j] << "\t";
}
output << "\n";
}
output.close();
system("PAUSE");
return 0;
}
It's a typo!
s = smoothNoise(floorX,floorY);
t = smoothNoise(floorX+1,floorY);
u = smoothNoise(floorY,floorY+1);
v = smoothNoise(floorX+1,floorY+1);
Try:
u = smoothNoise(floorX, floorY +1)
This explains why the diagonal didn't have the blocky appearance (where x=y), and why many of the common feature shapes are subtly off in a mirrored and skewed fashion.
Since it is generally obvious that rand2(floor(y), floor(y)+1) != rand2(floor(x), floor(y+1)) the cell discontinuity will result.
Finding no mathematical error in your implementation, I suspect this is a number format issue.
Such block patterns are created when the grid point values are not actually the same when fetched from different sides - when rand2(floor(n) +1 ,y) != rand2(floor(n+1) ,y)
To fix it, declare floorX to be an int or long instead, and pass it as such to smoothNoise() and rand2().
This can happen due to floating point error in the representation of the Integer values floorX , floorX + 1. The epsilon of magnitude ulp or less can have either sign. the results of addition [floor(n) + 1] and flooring directly [floor(n+1)] are bound by different code, and so need not share a pattern of choosing which side to err on. When the results err on different sides, the int type cast strips the 0.99999999999 and the 0.0000000001 equally, treating the mathematically equivalent numbers as different.