exprtk/exprtk_simple_example_23.cpp

137 lines
6.8 KiB
C++
Raw Permalink Normal View History

/*
**************************************************************
* C++ Mathematical Expression Toolkit Library *
* *
* Simple Example 23 *
* Author: Arash Partow (1999-2024) *
* URL: https://www.partow.net/programming/exprtk/index.html *
* *
* Copyright notice: *
* Free use of the Mathematical Expression Toolkit Library is *
* permitted under the guidelines and in accordance with the *
* most current version of the MIT License. *
* https://www.opensource.org/licenses/MIT *
* SPDX-License-Identifier: MIT *
* *
**************************************************************
*/
#include <cstdio>
#include <string>
#include "exprtk.hpp"
template <typename T>
void real_1d_discrete_fourier_transform()
{
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
typedef exprtk::function_compositor<T> compositor_t;
typedef typename compositor_t::function function_t;
const T sampling_rate = 1024.0; // ~1KHz
const T N = 8 * sampling_rate; // 8 seconds worth of samples
std::vector<T> input (static_cast<std::size_t>(N),0.0);
std::vector<T> output(static_cast<std::size_t>(N),0.0);
exprtk::rtl::io::println<T> println;
symbol_table_t symbol_table;
symbol_table.add_vector ("input" , input );
symbol_table.add_vector ("output" , output );
symbol_table.add_function ("println" , println );
symbol_table.add_constant ("N" , N );
symbol_table.add_constant ("sampling_rate", sampling_rate);
symbol_table.add_pi();
compositor_t compositor(symbol_table);
compositor.load_vectors(true);
compositor.add(
function_t("dft_1d_real")
.var("N")
.expression
(
" for (var k := 0; k < N; k += 1) "
" { "
" var k_real := 0.0; "
" var k_imag := 0.0; "
" "
" for (var i := 0; i < N; i += 1) "
" { "
" var theta := 2pi * k * i / N; "
" k_real += input[i] * cos(theta); "
" k_imag -= input[i] * sin(theta); "
" }; "
" "
" output[k] := hypot(k_real,k_imag); "
" } "
));
const std::string dft_program =
" "
" /* "
" Generate an aggregate waveform comprised of three "
" sine waves of varying frequencies and amplitudes. "
" */ "
" var frequencies[3] := { 100.0, 200.0, 300.0 }; /* Hz */ "
" var amplitudes [3] := { 10.0, 20.0, 30.0 }; /* Power */ "
" "
" for (var i := 0; i < N; i += 1) "
" { "
" var time := i / sampling_rate; "
" "
" for (var j := 0; j < frequencies[]; j += 1) "
" { "
" var frequency := frequencies[j]; "
" var amplitude := amplitudes [j]; "
" var theta := 2 * pi * frequency * time; "
" "
" input[i] += amplitude * sin(theta); "
" } "
" }; "
" "
" dft_1d_real(input[]); "
" "
" var freq_bin_size := sampling_rate / N; "
" var max_bin := ceil(N / 2); "
" var max_noise_level := 1e-5; "
" "
" /* Normalise amplitudes */ "
" output /= max_bin; "
" "
" println('1D Real DFT Frequencies'); "
" "
" for (var k := 0; k < max_bin; k += 1) "
" { "
" if (output[k] > max_noise_level) "
" { "
" var freq_begin := k * freq_bin_size; "
" var freq_end := freq_begin + freq_bin_size; "
" "
" println('Index: ', k,' ', "
" 'Freq. range: [', freq_begin, 'Hz, ', freq_end, 'Hz) ', "
" 'Amplitude: ', output[k]); "
" } "
" } "
" ";
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
parser.compile(dft_program,expression);
expression.value();
}
int main()
{
real_1d_discrete_fourier_transform<double>();
return 0;
}