Rocksolid Light

Welcome to Rocksolid Light

mail  files  register  newsreader  groups  login

Message-ID:  

The universe does not have laws -- it has habits, and habits can be broken.


devel / comp.lang.forth / Momentary Fourier Transform

SubjectAuthor
o Momentary Fourier Transformmhx

1
Momentary Fourier Transform

<01a4c9588d0ae3c4a9eb98acddec30fc@www.novabbs.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=25999&group=comp.lang.forth#25999

  copy link   Newsgroups: comp.lang.forth
Path: i2pn2.org!.POSTED!not-for-mail
From: mhx@iae.nl (mhx)
Newsgroups: comp.lang.forth
Subject: Momentary Fourier Transform
Date: Thu, 25 Jan 2024 19:05:11 +0000
Organization: novaBBS
Message-ID: <01a4c9588d0ae3c4a9eb98acddec30fc@www.novabbs.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Info: i2pn2.org;
logging-data="547583"; mail-complaints-to="usenet@i2pn2.org";
posting-account="t+lO0yBNO1zGxasPvGSZV1BRu71QKx+JE37DnW+83jQ";
User-Agent: Rocksolid Light
X-Rslight-Posting-User: 59549e76d0c3560fb37b97f0b9407a8c14054f24
X-Spam-Checker-Version: SpamAssassin 4.0.0
X-Rslight-Site: $2y$10$nKe7pm7nlY3KDGpGQioJlODZ7Hzv0hWhwHfrbC8/mLPchdG4SdxsS
 by: mhx - Thu, 25 Jan 2024 19:05 UTC

This is an relatively unknown Fourier method that is very suitable
for generating harmonic amplitudes on a sample-by-sample basis.
As such it is interesting for use in audio tools and circuit
simulation. The method can compete with the FFT, especially when
only a few harmonics are needed and the base frequency is known.

I have to admit that I initially coded this in MATLAB. However,
only when I redid it again in Forth the details became really
clear. The iForth code is 5 times faster than MATLAB.

The results are visually checked through Gnuplot. iForth provides
a MATLAB-like interface to that program. I've added a link to
a pdf on my Github repository.

-marcel

-- --------------------------------------------------
https://github.com/mhx-gh/SYSSIM/blob/master/mft.pdf
-- --------------------------------------------------
(*
* LANGUAGE : ANS Forth with extensions
* PROJECT : Forth Environments
* DESCRIPTION : The Momentary Fourier Transform
* CATEGORY : Tool for circuit simulation
* AUTHOR : Marcel Hendrix
* LAST CHANGE : 21:05:01, January 22, 2024, Marcel Hendrix
*)

NEEDS -miscutil
NEEDS -gaussj
NESTING @ 1 =
[IF] NEEDS -gnuplot
[THEN]
REVISION -MFT "--- Momentary FFT Version 0.03 ---"

PRIVATES

DOC
(*
S. Albrecht, I. Cumming and J. Dudas, "The momentary Fourier
transformation derived from recursive matrix transformations,"
Proceedings of 13th International Conference on Digital Signal
Processing, Santorini, Greece, 1997, pp. 337-340 Vol. 1.
Compute a maximum of N harmonics from a signal's N-point sample
record. Complex arithmetic is needed.

The nice thing about the algorithm is that, because the result is
build sample by sample, one doesn't need to have the (equidistant)
samples in a block of size N.
When sending a repeating waveform with N samples per cycle, a plot of
the result shows the amplitude of the N harmonics changing during the
first cycle, resulting in the expected values at the end of that cycle.
From that point onwards the amplitude of the harmonics stays constant.
The plot shows transients when the signal changes between blocks
of N samples.

For use in iSPICE, preface with a SAMPLEr (not a samplehold!) that
triggers (MFT) for every sample taken. The output of the MFT subcircuit
can contain upto N output nodes providing the value of the harmonic
amplitudes. The *phases* of these harmonics can be displayed, however,
they change N times per basic interval (by 360/N degrees). A way to
decide on a meaningful start of the sample block is needed when
requiring phase.
*)
ENDDOC

0 VALUE N PRIVATE -- how many samples there are in a cycle
DOUBLE DARRAY x{ PRIVATE -- the input sample buffer
COMPLEX DARRAY y{ PRIVATE -- contains N Fourier coefficients of x{.
COMPLEX DARRAY twiddle{ PRIVATE -- turns the transformation into a DFT

-- The FFT twiddle factors are: twiddle(k) = exp(-2*pi*k/N)
-- but here we want 1 / twiddle(k) = exp(2*pi*k/N).
-- The paper makes this a matrix, but it is faster as a vector.
: (MFT) ( N -- y{ ) ( F: xin -- )
TO N
y{ CDIM N \ we want to re-initialize when N changes
<> IF x{ N }malloc
y{ N }malloc
twiddle{ N }malloc malloc-fail? ?ALLOCATE
( xin ) x{ N 1- } DF!
PI*2 N S>F F/
N 0 ?DO FDUP I S>F F* FEXP(jX) twiddle{ I } Z! LOOP
FDROP
y{ EXIT
ENDIF
\ apply the MFT to sample xin
x{ 0 } DF@ FLOCAL sos \ shifted-out sample
x{ 1 } x{ 0 } N 1- DFLOATS MOVE \ circshift (x, LEFT)
( xin ) x{ N 1- } DF!
N 0 ?DO
x{ N 1- } DF@
sos F- REAL>Z \ (xin - prev + y(i)) * twiddle(i)
y{ I } DUP Z@ Z+
twiddle{ I } Z@ Z*
( addr -- ) Z!
LOOP y{ ; \ needs scaling by 2/N & DC term/2

NESTING @ 1 =
[IF] ( plotting with Gnuplot )

100e FVALUE fin
#64 VALUE Ns
2 VALUE m

m Ns * DOUBLE ARRAY t{
m Ns * DOUBLE ARRAY s{
Ns m Ns * DOUBLE MATRIX f{{

fin Ns S>F F* FVALUE fs
fs 1/F FVALUE Ts

: INIT ( -- ) \ construct a signal with H0=0.1, H1=0.8, H2=0.6, H3=0.4
0e FLOCAL time
m Ns * 0 ?DO Ts I S>F F* FDUP TO time t{ I } DF!
0.1e
fin PI*2 F* time F* FSIN 0.8e F* F+
fin F2* PI*2 F* time F* FSIN 0.6e F* F+
fin 3e F* PI*2 F* time F* FSIN 0.4e F* F+
s{ I } DF!
LOOP ;

: GET-RESULTS ( -- )
2e Ns S>F F/ FLOCAL 2/N
m Ns * 0 ?DO s{ I } DF@ Ns (MFT) ( y{ -- )
>S Ns 0 ?DO S I } Z@ ZABS
2/N F*
I 0= IF F2/ ENDIF ( dc )
f{{ I J }} DF!
LOOP -S
LOOP ;

: PLOT-RESULTS ( -- )
0 FIGURE CLF
S" MFT shell test program" TITLE
2 1 SUBPLOT
S" amplitude [V]" YLABEL
TRUE GRID TRUE ZOOM
[PHOLD t{ s{ S" blue-" PLOT PHOLD]
S" amplitude [%]" YLABEL
S" time [ms]" XLABEL
TRUE GRID TRUE ZOOM
[PHOLD
0 TO subp
S" dc" S" h1" S" h2" S" h3" -4 LEGEND
t{ f{{ 0 =rowget 100e =scalemat S" black-" PLOT
t{ f{{ 1 =rowget 100e =scalemat S" red-" PLOT
t{ f{{ 2 =rowget 100e =scalemat S" blue-" PLOT
t{ f{{ 3 =rowget 100e =scalemat S" magenta-" PLOT
PHOLD]
SPEND ;

: MFT_shell ( -- ) INIT GET-RESULTS PLOT-RESULTS ;

:ABOUT CR ." Try: MFT_shell"
CR ." Expect DC = 10%, H1=80%, H2=60%, H3=40% " ;

.ABOUT -MFT
[THEN]

DEPRIVE

(* End of Source *)

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor