{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset0 Arial;}} {\*\generator Msftedit 5.41.21.2508;}\viewkind4\uc1\pard\tx5220\b\f0\fs20\\ FHT Examples \par \par \{ The FHT User Word Set\b0\par \par \ul User Variables\par \par \ulnone >dscale Executing >dscale changes the default (1000000) value. This is used to scale data. If necessary, \par both the dataset and dscale must be reduced by 10 to prevent overflow if the power spectrum is calculated. \par In this case, overflow is indicated if the results are negative. Changing dscale does not affect the scaling of\par Sin/Cos values, which are scaled so that 1000000 = 1. \par \par N, >N The length (long) of the current selected dataset. >N changes N to .\par \par tmp1, tmp2, tmp3 Variables (longs) which may be used in user defined words for temprary storage. \par For example, tmp1 L@ puts its value on the data stack, wheras tmp1 L! stores \par at tmp1 address.\par \par \ul Defining Words\ulnone\par \par variable x0 l, x1 l, x2 l,m x3 l, ....... xn l, Defines a table (list) of n+1 longs where the first element \par (x0) is set to n. Used to define datasets.\par \par n vector defines as a vector of n+1 longs, where the first element (0) will store n. Only those vectors\par needed by a specific problem are user defined.\par \par \ul Deferred Words \par \par \ulnone The first word in each of the following rows is deferred until activated by the -IS words, e.g., HX-IS TEST1 (TEST1 is a \par previously defined dataset). Executing n Hx leaves the value in the nth cell on the data stack, while n >Hx \par changes the nth cell to . Executing (hx) leaves its address on the stack. Hx is the "work horse" of the FHT\par method. Gx is only used to hold the fht of the kernel in the convolution method.\par \par (hx), Hx, >Hx, HX-IS \par (gx), Gx, >Gx, GX-IS\par \par In & Out are general purpose vectors used to support various data manipulation techniques, e.g., padding & joining.\par The user must define a vector when needed. For example, 17 (n+1) vector \i tin\i0 IN-IS \i tin\i0 . Executing \i tin\i0 leaves its address\par on the stack, n In leaves the nth value on the stack, and >In is used to assign values.\par \par (in), In, >In, IN-IS \par (out), Out, >Out, OUT-IS \ul\par \ulnone\par The following words are used to store the indicated values. Vectors must be defined in each case.\par \par (re), Re, >Re, RE-IS Real component of the fft.\par (im), Im, >Im, IM-IS Imaginary component of the fft.\par (ps), Ps, >Ps, PS-IS Power Spectrum\par (mag), Mag, >Mag, MAG-IS Magnitude\par \par \ul Functions\par \par \ulnone\b FHT \b0 Calculates the Fast Hartley Transform of a dataset pointed to by Hx. The dataset is replaced by the fht.\ul\par \ulnone Calculates the inverse of the fht stored in the active dataset. Since results are not "scaled", that is, not divided by N,\par the output will be N times the original data. Note that FHT contains words which displays the elapsed time used by \par the FHT function in microseconds.\par \par \b FFT \b0 Calculates Re and Im fft components. Re and Im vectors must be defined and activated. Not really necessary in \par most applications. \par \par \b POWSP \b0 Calculates the power spectrum from the fht and stores it in the previously defined vector pointed to by Ps.\par \par \b MAG \b0 Calculates the magnitude from the power spectrum and stores it in the previously defined vector pointed to by Mag.\par \par \b CONVOLVE \b0 Calculates the convolution of two datasets of equal length (power of 2) using the fhts stored in Hx and Gx. The\par result is stored in the dataset pointed to by Hx. Gx is the fht of the kernel. This method is defined for only \par symmetrical datasets. Convolution is cyclic unless the datasets are padded with zeros, i.e., their length is \par doubled. This function may be used for autocorrelation of even datasets.\par \par \ul Utility Words\ulnone\par \par addr \b clearDATA\b0 Sets all vector data cells to 0 beginning at address addr. Example: \i tin\i0 clearDATA sets vector pointed \par to by In to 0. \par \par addr \b scaleDATA \b0 Divides data at addr by N. \par \par addr1 addr2 \b moveDATA\b0 Moves N longs (including N) from addr1 to addr2. \par Example: TEST1 tin moveDATA stores TEST1 dataset in vector pointed to by In.\par \par addr1 addr2 joinDATA Moves N longs (N is not included) to end of dataset at addr2. \par \par \b reverseDATA \b0 Places data in vector pointed to by In in reverse order in vector pointed to by Out.\par \par addr \b SHOW \b0 Displays the vector at address addr.\par \par \b DISPLAY \b0 Displays a table of data, each row showing the In, Hx, Re, Im, Ps, and Mag vectors in that order. \par In is set to point to the unprocessed dataset.\b\par \b0\par \par \b\}\par \par \b0 fl\par \par fswrite fht_examples.f\par \b\par \par \b0 decimal \b \par \par \b0\\ \i Define user vectors. (Set larger than needed for most examples)\par \i0\par 65 vector tre\par RE-IS tre\par 65 vector tim\par IM-IS tim\par 65 vector tps\par PS-IS tps\par 65 vector tmag\par MAG-IS tmag\par 129 vector tin\par IN-IS tin\par 129 vector tout\par OUT-IS tout\par \par \par \par \par \\ \i Define test data tables.\par \par \i0\\ Ramp \par variable TEST1 8 l, 1000000 l, 2000000 l, 3000000 l, 4000000 l, 5000000 l, 6000000 l, 7000000 l, 8000000 l,\par \par \\ Smooth Binomial Bump\par variable TEST2 16 l, 2000000 l, 1500000 l, 600000 l, 100000 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, \par 100000 l, 600000 l, 1500000 l,\par \par \par \\ Single Sin wave\par variable TEST3 32 l, 0 l, 195090 l, 382683 l, 555570 l, 707107 l, 831470 l, 923880 l, 980785 l, 1000000 l, 980785 \par l, 923880 l, 832470 l, 707107 l, 555570 l, 382683 l, 195090 l, 0 l, -195090 l, -382683 l, -555570 l, -707107 l, -831470 \par l, -923880 l, -980785 l, -1000000 l, -980785 l, -923880 l, -832470 l, -707107 l, -555570 l, -382683 l, -195090 l, \par \par \\ Double Sin Wave\par variable TEST4 64 l, 0 l, 195090 l, 382683 l, 555570 l, 707107 l, 831470 l, 923880 l, 980785 l, 1000000 l, 980785 \par l, 923880 l, 832470 l, 707107 l, 555570 l, 382683 l, 195090 l, 0 l, -195090 l, -382683 l, -555570 l, -707107 l, -831470 \par l, -923880 l, -980785 l, -1000000 l, -980785 l, -923880 l, -832470 l, -707107 l, -555570 l, -382683 l, -195090 \par l, 0 l, 195090 l, 382683 l, 555570 l, 707107 l, 831470 l, 923880 l, 980785 l, 1000000 l, 980785 \par l, 923880 l, 832470 l, 707107 l, 555570 l, 382683 l, 195090 l, 0 l, -195090 l, -382683 l, -555570 l, -707107 l, -831470 \par l, -923880 l, -980785 l, -1000000 l, -980785 l, -923880 l, -832470 l, -707107 l, -555570 l, -382683 l, -195090 l,\par \par \\ Generating a Cos Wave\par variable TEST5 32 l, 0 l, 500000 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 0 l,\par 0 l, 0 l, 0 l, 0 l, 0 l, 0 l, 500000 l, \par \par \\ TEST6 to be convolved with TEST7\par variable TEST6 8 l, 2000000 l, 1000000 l, 0 l, 0 l, 0 l, 0 l, 1000000 l, \par \par variable TEST7 8 l, 1000000 l, 4000000 l, 6000000 l, 4000000 l, 1000000 l, 0 l, 0 l, 0 l,\par \par \\ Example for Autocorrelation\par variable TEST8 8 l, 6000000 l, 4000000 l, 1000000 l, 0 l, 0 l, 0 l, 1000000 l, 4000000 l, \par \par \pard\\ ( n -- ) Stores n random numbers ranging from 0 to dscale in the In vector (previously defined as n+1 cells). \par : rndDATA dup 0 >In 1+ 1 do rnd dscale 255 */ i >In loop ;\par \par ...\par \par \par \\ \i Example 1 - A basic FHT Analysis\par \par \i0 TEST1 tin moveDATA \\ stores dataset\par HX-IS TEST1 \\ sets TEST1 as the object\par FHT FFT POWSP MAG \\ run all functions\par DISPLAY \\ see results\par FHT \\ repeat to regenerate dataset \par TEST1 scaleDATA \\ divide by N \par TEST1 SHOW \\ display output of inverse fht\par \par \par \\ Let us combine these commands into a single word to simplify making multiple runs.\par : RUN FHT FFT POWSP MAG DISPLAY ;\par \par \\ Repeat using TEST2. You will note that the fht and fft of this dataset are equal (the imaginary component is 0).\par TEST2 tin moveDATA HX-IS TEST2 RUN\par \par \\ \i Example 2 - Pure Sin Wave - Using the FHT to Synthesize Waves\i0\par \par \\ TEST3 is a single sin wave. TEST4 doubles TEST3. \i\par \i0 TEST3 tin moveDATA HX-IS TEST3 RUN\par \\ and\par TEST4 tin moveDATA HX-IS TEST4 RUN\par \\ and do the inverse\par FHT TEST4 scaleDATA TEST4 SHOW\par \par \\ Note that in both cases the fft real component is 0 and the imaginary component is the negative of the fht.\par \\ The inverse reproduces the original data.\par \i\par \i0\\ Do the following: \par TEST5 tin moveDATA HX-IS TEST7 FHT TEST5 SHOW\par \par \\ The result is a Cos wave. Other, more complex waves ( combinations of sin & cos) can be generated by taking\par \\ the inverse FHT of datasets consisting of only real elements. Another application would be to generate a cos or sin\par \\ table at a user defined resolution.\par \par \par \\ \i Example 3 - Convolution & Autocorrelation \i0\par \par HX-IS TEST6 FHT\par GX-IS TEST6 \\ Gx points to fht of TEST8\par HX-IS TEST7 FHT \\ Hx points to fht of TEST9\par TEST7 tin moveDATA \\ In stores fht of TEST9\par CONVOLVE \\ Hx stores convolution output\par TEST6 SHOW \\ display fht of test6 \par tin SHOW \\ display fht of test7\par TEST7 SHOW \\ display convolution result (not scaled) \par \par HX-IS TEST10\par FHT\par GX-IS TEST10\par CONVOLVE \\ autocorrelation of TEST10\par TEST10 SHOW\par \par \\ \i Example 4 - Zero-Padding & Joining Datasets\i0\par \par \\ Zero-padding is required to avoid cyclic convolution in which results are overlapped. Padding doubles the dataset\par \\ length. The following steps zero-pad TEST2. We will use the preciously defined vector tin pointed to by In.\par \par tin clearDATA TEST2 tin moveDATA 32 0 >In tin SHOW \par \par \\ Two datasets of equal length can be joined leaving the result in tout, a previously defined vector pointed to by Out.\par \par TEST1 tin moveDATA tout clearDATA TEST1 tout moveDATA tin tout joinDATA 16 0 >Out tout SHOW\par \par \\ or\par \par TEST1 tin moveDATA tout clearDATA reverseDATA tin tout joinDATA 16 0 >Out tout SHOW\par \par \par \\ \i Example 5 - FHT Timing\par \par \i0\\ The word rndDATA will be used to fill vectors (In) of different lengths to compare the time required by the FHT function \par \\ for different size datasets.Results are shown in millseconds. \par \par 16 rndDATA HX-IS tin FHT 21.3\par 32 rndDATA HX-IS tin FHT 52.8\par 64 rndDATA HX-IS tin FHT 125.6\par 128 rndDATA HX-IS tin FHT 292.3\par 513 vector jin\par 512 rndDATA HX-IS jin FHT 1496\par \par \par \{\par These results indicate that this forth version is about 3x slower than the spin version of FHT. However, timing \par of this order of magnitude should not be an issue for most problems. In any case, the advantages of the forth version, e.g.,\par easy manipution of data, more than compensate for the execution time disadvantage. The Fast Hartley Transform is the \par way to accomplish those tasks usually performed using the FFT, as least on microcontrollers.\par \} \par \par \par \par \par \par \par \par \par \par \i\par \i0\par \par \par \i \par \i0\par \par \par \par \par \par \par \i\par \i0\par \par \par \par \par }