/* ************************************************************** * 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 #include #include "exprtk.hpp" template void real_1d_discrete_fourier_transform() { typedef exprtk::symbol_table symbol_table_t; typedef exprtk::expression expression_t; typedef exprtk::parser parser_t; typedef exprtk::function_compositor 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 input (static_cast(N),0.0); std::vector output(static_cast(N),0.0); exprtk::rtl::io::println 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(); return 0; }