/* MCL Copyright (c) 2012-18, Enzo De Sena All rights reserved. Authors: Enzo De Sena, enzodesena@gmail.com */ #include "vectorop.h" #include #include "mcltypes.h" #include "pointwiseop.h" #include "transformop.h" #include #include "comparisonop.h" #include #include #ifdef MCL_APPLE_ACCELERATE #include #endif namespace mcl { void Multiply(const Real* input_data, const Int num_samples, const Real gain, Real* output_data) noexcept { #if defined(MCL_APPLE_ACCELERATE_MMA) && MCL_APPLE_ACCELERATE_MMA #ifdef MCL_DATA_TYPE_DOUBLE vDSP_vmulD(input_data, 1, &gain, 0, output_data, 1, num_samples); #else vDSP_vmul(input_data, 1, &gain, 0, output_data, 1, num_samples); #endif #else for (Int i=0; i LinSpace(Real min, Real max, Int num_elements) noexcept { // This is to mimic Matlab's behaviour. if (num_elements <= 1) { return UnaryVector(max); } Real interval = max-min; Real slot = interval / ((Real) (num_elements-1)); std::vector output(num_elements); for (Int i=0; i Ones(Int length) noexcept { return std::vector(length, (Real) 1.0); } Real Sum(const std::vector& input) noexcept { Real output(0.0); for (Int i=0; i<(Int)input.size(); ++i) { output += input[i]; } return output; } Real Mean(const std::vector& input) noexcept { return Sum(input) / ((Real) input.size()); } Real Mean(const std::vector& input, const std::vector& weights) noexcept { ASSERT(input.size() == weights.size()); ASSERT(IsNonNegative(weights)); // Normalise the weigths std::vector normalised_weights = Multiply(weights, 1.0/Sum(weights)); ASSERT(IsEqual(Sum(normalised_weights), 1.0)); return Sum(Multiply(input, normalised_weights)); } Real Geomean(const std::vector& input) noexcept { // TODO: Throw error for negative entries return Pow(Prod(input), 1.0/((Real)input.size())); } Real Std(const std::vector& input) noexcept { return sqrt(Var(input)); } Real Var(const std::vector& input) noexcept { Real mean = Mean(input); Real output(0.0); for (Int i=0; i<(Int)input.size(); ++i) { output += pow(input[i] - mean,2.0); } return output/((Real) (input.size()-1)); } Real Var(const std::vector& input, const std::vector& weights) noexcept { ASSERT(IsNonNegative(weights)); Real weighted_mean = Mean(input, weights); std::vector temp = Pow(Add(input, -weighted_mean), 2.0); std::vector norm_weights = Multiply(weights, 1.0/Sum(weights)); return (Sum(Multiply(norm_weights, temp))); } std::vector Split(const std::string &s, char delim) noexcept { std::vector elems; std::stringstream ss(s); std::string item; while(std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } std::vector Poly(const std::vector roots) noexcept { Int n(Length(roots)); std::vector output = Zeros(n+1); // c = [1 zeros(1,n,class(x))]; output[0] = 1.0; // for j=1:n for (Int j=1; j<=n; ++j) { // c(2:(j+1)) = c(2:(j+1)) - e(j).*c(1:j); std::vector temp(output); for (Int i=2; i<=(j+1); ++i) { output[i-1] = temp[i-1] - roots[j-1]*temp[i-2]; } } return output; } std::vector Poly(const std::vector roots) noexcept { return Poly(ComplexVector(roots)); } std::vector ColonOperator(const Real from, const Real step, const Real to) noexcept { ASSERT(std::isgreater(step, 0)); std::vector output; output.push_back(from); Int i = 1; while (std::islessequal(((Real) i)*step+from, to)) { output.push_back(((Real) i++)*step+from); } return output; } std::vector TukeyWin(const Int length, const Real ratio) noexcept { if (length == 1) { return UnaryVector(1.0); } if (ratio <= 0) { return Ones(length); } else if (ratio >= 1.0) { return Hann(length); } else { std::vector t = LinSpace(0.0, 1.0, length); // Defines period of the taper as 1/2 period of a sine wave. Real per = ratio/2.0; Int tl = (Int) floor(per*(((Real) length)-1.0))+1; Int th = length-tl+1; // Window is defined in three sections: taper, constant, taper // w1 = ((1+cos(PI/per*(t(1:tl) - per)))/2); std::vector w = Ones(length); for (Int i=0; i Hann(const Int length) noexcept { std::vector w = Ones(length); for (Int i=0; i& vector, Real l_norm) noexcept { const Int num_elements = vector.size(); Real output = 0.0; for (Int i=0; i& input) noexcept { const Int num_elem = input.size(); for (Int i=0; i Cov(const std::vector& x, const std::vector& y) noexcept { std::vector > input(2); input[0] = x; input[1] = y; return Cov(input); } Matrix Cov(const std::vector >& input) noexcept { const Int N = input.size(); Matrix output(N, N); for (Int i=0; i& x, const std::vector& y) noexcept { const Int N = x.size(); ASSERT(N == (Int)y.size()); Real output = Sum(Multiply(Add(x, -Mean(x)), Add(y, -Mean(y)))); // In case N>1 use the unbiased estimator of covariance. output = (N > 1) ? output/((Real) (N-1)) : output/((Real) (N)); return output; } std::vector CumSum(const std::vector& input) noexcept { const Int N = input.size(); std::vector output(input.size()); output[N-1] = Sum(input); for (Int i=N-2; i>=0; --i) { output[i] = output[i+1]-input[i+1]; } return output; } std::vector Hamming(const Int length) noexcept { const Real alpha = 0.54; const Real beta = 1.0-alpha; std::vector w = Ones(length); for (Int i=0; i > Enframe(const std::vector& input, const std::vector& window, const Int frame_increment) noexcept { std::vector > output; Int i = 0; while ((i + window.size())<=input.size()) { Int from_sample = i; Int to_sample = i + window.size()-1; ASSERT(from_sample>=0 && from_sample<(Int)input.size()); ASSERT(to_sample>=0 && to_sample<(Int)input.size()); output.push_back(Multiply(Elements(input, from_sample, to_sample), window)); i = i + frame_increment; } return output; } std::vector OverlapAdd(const std::vector >& frames, const std::vector& window, const Int frame_increment) noexcept { const Int num_frames = frames.size(); std::vector output(window.size()+(num_frames-1)*frame_increment); for (Int frame_i=0; frame_i ConvertToComplex(std::vector input) noexcept { std::vector output; for (Int i=0; i<(Int)input.size(); ++i) { output.push_back(Complex(input[i], 0.0)); } return output; } } // namespace mcl