Skip to content
Extraits de code Groupes Projets
Valider ca449d97 rédigé par Hugo TRACHINO's avatar Hugo TRACHINO
Parcourir les fichiers
parents bf64fe46 8afa20cb
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
#pragma once
#include <random>
#include <iostream>
#include <fstream>
#include "../types.h"
#include <complex>
/*
* Code translated from Matlab base functions
* matlab translation guide : https://eigen.tuxfamily.org/dox/AsciiQuickReference.txt
*/
//-------------------------------------------------------------------------------------------------
// VARIOUS
const number pi = M_PI;
// squares a number
template<typename T> inline T squared(const T& x)
{
return x*x;
}
//-------------------------------------------------------------------------------------------------
// ALGEBRA
// build a vector with values in the given interval
Vector make_vector(const int fromValue, const int toValue, const int by = 1)
{
int size = 1 + (toValue - fromValue) / by;
Vector result(size);
int currentValue = fromValue;
for(int i = 0; i < size; i++)
{
result(i) = currentValue;
currentValue += by;
}
return result;
}
// repeats a column vector n times in order to build a matrix
Matrix repmat(const Vector& v, const int colNumber)
{
Matrix result(v.size(), colNumber);
for(int col = 0; col < colNumber; col++)
{
result.col(col) = v;
}
return result;
}
// solves m = m1 \ m2
inline ComplexMatrix mldivide(const ComplexMatrix& m1, const ComplexMatrix& m2)
{
//return m1.colPivHouseholderQr().solve(m2);
return m1.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(m2); // you can use JacobiSVD for improved precision
}
// returns an hermitian matrix where v is the first row and conj(v) the first column
Matrix toeplitz(const Vector& v)
{
auto size = v.size();
Matrix result(size, size);
for(int row=0; row<size; row++)
{
for(int col=0; col<size; col++)
{
// complex
/*number value = v(std::abs(row - col));
if(row > col)
{
value = Sstd::conj(value);
}
result(row,col) = value;*/
// real
result(row,col) = v(std::abs(row - col));
}
}
return result;
}
// flip the column and rows
inline Matrix flip(Matrix mat)
{
Matrix matflipr = mat.rowwise().reverse(); // fliplr
Matrix matflipc = matflipr.colwise().reverse(); // flipud
return matflipc;
}
//-------------------------------------------------------------------------------------------------
// POLYNOMIAL
/*
* evaluates a polynomial on the given data
* use Horner's scheme
* NOTE: one could use a more numerically stable algorithm
*/
Vector polyval(const Polynomial& pol, const Vector& x)
{
Vector result = Vector::Zero(x.size());
for(const auto& coef : pol)
{
result = result.binaryExpr(x, [coef](const number& result, const number& x){return result*x + coef;});
}
return result;
}
//-------------------------------------------------------------------------------------------------
// RANDOM HELPING FUNCTION
const unsigned int n = 65535;//0xFFFF;
const unsigned int m = 16807;
const unsigned int b = 0;
static long seed = 43690;//0xAAAA;
// generate an uniformaly distributed random number sampled from [0;0x7FFFFFFF]
long uniform() {
long unsigned int hi = m * (seed & n);
long unsigned int lo = m * (seed >> 16);
lo+= (hi & 32767) << 16;
lo+= hi >> 15;
if (lo > 2147483647) //0x7FFFFFFF)
lo -= 2147483647; //0x7FFFFFFF;
seed=(long) lo;
return seed ;
}
//--------------------------------------------------------------------------------------------------
// RANDOM
// generate an uniformaly distributed random number sampled from [-1;1]
inline number randu()
{
//on le veut entre -1 et 1 / pour l'instant on l'a entre 0 et 1
number result = uniform()/2147483647; //(double)0x7FFFFFFF;
// number result = (uniform() - (number)3xFFFFFFF.8)/(number)3xFFFFFFF.8);
return result;
// throw std::logic_error("Function not yet implemented.");
}
// generates a vector of the given size, the entries of the vector are all complex number
// their real and imaginary parts are uniformaly distributed random number sampled from [-1;1]
ComplexVector randu(int size)
{
ComplexVector complexVector(size);
std::complex<number> mycomplex;
for(int i = 0; i < size; i++)
{
std::complex<number> mycomplex(randu(), randu());
complexVector(i) = mycomplex;
}
return complexVector;
//throw std::logic_error("Function not yet implemented.");
}
// generate a normally distributed random number
// sampled from a distribution with mean 0 and std 1
inline number randn()
{
number res;
number U0 = uniform()/2147483647;//(double)0x7FFFFFFF;
number U1 = uniform()/2147483647;//(double)0x7FFFFFFF;
res = sqrt(-2 * log(U0)) * cos(2 * M_PI * U1);
return res;
// throw std::logic_error("Function not yet implemented.");
}
// generates a vector of the given size, the entries of the vector are all complex number
// their real and imaginary parts are sampled from a normal distribution with mean 0 and std 1
ComplexVector randn(int size)
{
// NOTE: this can be built on the previous function
ComplexVector complexVector(size);
std::complex<number> mycomplex;
for(int i = 0; i < size; i++)
{
std::complex<number> mycomplex(randn(), randn());
complexVector(i) = mycomplex;
}
return complexVector;
//throw std::logic_error("Function not yet implemented.");
}
//-------------------------------------------------------------------------------------------------
// IMPORT
/// import a vector of reals from a file
Vector loadRealVector(const std::string& file)
{
std::vector<number> result;
std::ifstream input(file);
number x;
while (input >> x)
{
result.push_back(x);
}
Vector output = Eigen::Map<Vector, Eigen::Unaligned>(result.data(), result.size());
return output;
}
/// import a vector of complex from a file
ComplexVector loadComplexVector(const std::string& file)
{
std::vector<complexNumber> result;
std::ifstream input(file);
number r;
number i;
while (input >> r)
{
input >> i;
complexNumber x(r,i);
result.push_back(x);
}
ComplexVector output = Eigen::Map<ComplexVector, Eigen::Unaligned>(result.data(), result.size());
return output;
}
//-------------------------------------------------------------------------------------------------
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter