Skip to content

Commit 7bf7cb8

Browse files
committed
docs: add examples
1 parent fdc5fe6 commit 7bf7cb8

File tree

7 files changed

+206
-80
lines changed

7 files changed

+206
-80
lines changed

lib/node_modules/@stdlib/fft/base/fftpack/rfftf/lib/c1_ref.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070
* @param {NonNegativeInteger} l1 - length parameter related to the FFT stage
7171
* @param {NonNegativeInteger} ido - dimension order
7272
* @returns {NonNegativeInteger} computed index
73+
*
74+
* @example
75+
* var out = c1Ref( 0, 1, 2, 4, 8 );
76+
* // returns 72
7377
*/
7478
function c1Ref( a1, a2, a3, l1, ido ) {
7579
return ( ( (a3*l1)+a2 ) * ido ) + a1;

lib/node_modules/@stdlib/fft/base/fftpack/rfftf/lib/c2_ref.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@
6868
* @param {NonNegativeInteger} a2 - index of second dimension
6969
* @param {integer} idl1 - stride related to the `l1` parameter
7070
* @returns {NonNegativeInteger} computed index
71+
*
72+
* @example
73+
* var out = c2Ref( 0, 1, 2 );
74+
* // returns 2
7175
*/
7276
function c2Ref( a1, a2, idl1 ) {
7377
return ( a2*idl1 ) + a1;

lib/node_modules/@stdlib/fft/base/fftpack/rfftf/lib/ch2_ref.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@
6868
* @param {NonNegativeInteger} a2 - index of second dimension
6969
* @param {integer} idl1 - stride related to the `l1` parameter
7070
* @returns {NonNegativeInteger} computed index
71+
*
72+
* @example
73+
* var out = ch2Ref( 0, 1, 2 );
74+
* // returns 2
7175
*/
7276
function ch2Ref( a1, a2, idl1 ) {
7377
return ( a2*idl1 ) + a1;

lib/node_modules/@stdlib/fft/base/fftpack/rfftf/lib/ch_ref.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070
* @param {NonNegativeInteger} radix - length parameter related to the FFT stage
7171
* @param {NonNegativeInteger} ido - dimension order
7272
* @returns {NonNegativeInteger} - calculated index
73+
*
74+
* @example
75+
* var out = chRef( 0, 1, 2, 4, 8 );
76+
* // returns 72
7377
*/
7478
function chRef( a1, a2, a3, radix, ido ) {
7579
return ( ( (a3*radix)+a2 ) * ido ) + a1;

lib/node_modules/@stdlib/fft/base/fftpack/rfftf/lib/index.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,28 @@
1919
'use strict';
2020

2121
/**
22-
* TODO: description.
22+
* Compute the forward real FFT.
2323
*
2424
* @module @stdlib/fft/base/fftpack/rfftf
2525
*
2626
* @example
27+
* var Float64Array = require( '@stdlib/array/float64' );
28+
* var rffti = require( '@stdlib/fft/base/fftpack/rffti' );
2729
* var rfftf = require( '@stdlib/fft/base/fftpack/rfftf' );
2830
*
29-
* // TODO
31+
* // Define the sequence length:
32+
* var N = 4;
33+
*
34+
* // Initialize a workspace array for the FFT:
35+
* var workspace = new Float64Array( ( 2*N ) + 34 );
36+
* rffti( N, workspace, 1, 0 );
37+
*
38+
* // Define a real-valued input sequence:
39+
* var x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] );
40+
*
41+
* // Perform the forward real FFT:
42+
* rfftf( N, x, 1, 0, workspace, 1, 0 );
43+
* // x => <Float64Array>[ 10.0, -2.0, -2.0, 0.0 ]
3044
*/
3145

3246
// MODULES //

lib/node_modules/@stdlib/fft/base/fftpack/rfftf/lib/main.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ var rfftf1 = require( './rfftf1.js' );
7979
* @param {integer} strideW - stride length for `workspace`
8080
* @param {NonNegativeInteger} offsetW - starting index for `workspace`
8181
* @returns {void}
82+
*
83+
* @example
84+
* var Float64Array = require( '@stdlib/array/float64' );
85+
* var rffti = require( '@stdlib/fft/base/fftpack/rffti' );
86+
*
87+
* // Define the sequence length:
88+
* var N = 4;
89+
*
90+
* // Initialize a workspace array for the FFT:
91+
* var workspace = new Float64Array( ( 2*N ) + 34 );
92+
* rffti( N, workspace, 1, 0 );
93+
*
94+
* // Define a real-valued input sequence:
95+
* var x = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] );
96+
*
97+
* // Perform the forward real FFT:
98+
* rfftf( N, x, 1, 0, workspace, 1, 0 );
99+
* // x => <Float64Array>[ 10.0, -2.0, -2.0, 2.0 ]
82100
*/
83101
function rfftf( N, r, strideR, offsetR, workspace, strideW, offsetW ) {
84102
var offsetT;
@@ -101,7 +119,7 @@ function rfftf( N, r, strideR, offsetR, workspace, strideW, offsetW ) {
101119
offsetT = offsetW + (N * strideW); // index offset for twiddle factors
102120
offsetF = offsetT + (N * strideW); // index offset for factors describing the sub-transforms
103121

104-
rfftf1( N, r, strideR, offsetR, workspace, strideW, offsetW, workspace, strideW, offsetT, workspace, strideW, offsetF ); // eslint-disable-line max-len
122+
rfftf1( N, r, offsetR, workspace, offsetW, workspace, offsetT, workspace, offsetF ); // eslint-disable-line max-len
105123
}
106124

107125

lib/node_modules/@stdlib/fft/base/fftpack/rfftf/lib/radf3.js

Lines changed: 155 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -62,94 +62,172 @@
6262

6363
// MODULES //
6464

65-
var sincos = require( '@stdlib/math/base/special/sincos' );
66-
var TWO_PI = require( '@stdlib/constants/float64/two-pi' );
67-
var chRef = require( './ch_ref.js' );
68-
var ccRef = require( './cc_ref.js' );
65+
var sin = require( '@stdlib/math/base/special/sin' );
66+
var cos = require( '@stdlib/math/base/special/cos' );
67+
var PI = require( '@stdlib/constants/float64/pi' );
6968

7069

7170
// VARIABLES //
7271

73-
var sc = sincos( ( 2 * TWO_PI ) / 3 );
74-
var taur = sc[ 1 ]; // -0.5
75-
var taui = -sc[ 0 ]; // 0.866025403784439
72+
var TAUR = cos( ( 2.0 * PI ) / 3.0 );
73+
var TAUI = sin( ( 2.0 * PI ) / 3.0 );
7674

7775

78-
// MAIN //
76+
// FUNCTIONS //
7977

8078
/**
81-
* Performs the forward FFT of length 3 for real-valued sequences.
79+
* Resolves an index into the input array.
80+
*
81+
* ## Notes
82+
*
83+
* In a forward real FFT, the previous stage writes its results as two "rows" per sub-sequence.
84+
*
85+
* Thus, when reading from an input array stored in linear memory, we can reinterpret the array as a three-dimensional logical view containing `L` independent sub-sequences having two "rows" (`even + odd` and `even - odd`, respectively) and where each "row" is arranged as `M*L` contiguous elements corresponding to interleaved real and imaginary components.
86+
*
87+
* Accordingly, the following is a logical view of an input array (zero-based indexing) which contains `L = 3` transforms and in which each sub-sequence has length `M = 4`:
88+
*
89+
* ```text
90+
* │ k = 0 k = 1 k = 2
91+
* │ ──────────────────────────────────────────────────────────────────────────→ k
92+
* j = 0 (even+odd) │ cc(0,0,0) ... cc(3,0,0) cc(0,1,0) ... cc(3,1,0) cc(0,2,0) ... cc(3,2,0)
93+
* │
94+
* j = 1 (even-odd) │ cc(0,0,1) ... cc(3,0,1) cc(0,1,1) ... cc(3,1,1) cc(0,2,1) ... cc(3,2,1)
95+
* └───────────────────────────────────────────────────────────────────────────→ i
96+
* ↑ ↑ ↑ ↑ ↑ ↑
97+
* i = 0 M-1 0 M-1 0 M-1
98+
* ```
99+
*
100+
* In the above,
101+
*
102+
* - `i` is the fastest varying index, which walks within one short sub-sequence corresponding to either the `even + odd` or `even - odd` row of the previous stage.
103+
* - `j` selects between the `even + odd` and `even - odd` row of the previous stage.
104+
* - `k` specifies the index of one of the `L` independent transforms we are processing.
105+
*
106+
* In linear memory, the three-dimensional logical view is arranged as follows:
107+
*
108+
* ```text
109+
* | cc(0,0,0)...cc(3,0,0) ... cc(0,2,0)...cc(3,2,0) | cc(0,0,1)...cc(3,0,1) ... cc(0,2,1)...cc(3,2,1) |
110+
* ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
111+
* 0 M-1 LM LM-1 (L+1)M (L+1)M-1 (2L-1)M 2LM-1
112+
* ```
82113
*
83114
* @private
84-
* @param {number} ido - number of real values for each transform
85-
* @param {number} l1 - length of the input sequences
86-
* @param {Float64Array} cc - input array containing sequences to be transformed
87-
* @param {number} ccOffset - offset for the input array
88-
* @param {Float64Array} ch - output array containing transformed sequences
89-
* @param {number} chOffset - offset for the output array
90-
* @param {Float64Array} wa1 - first array of twiddle factors
91-
* @param {number} wa1Offset - offset for the first twiddle factors array
92-
* @param {Float64Array} wa2 - second array of twiddle factors
93-
* @param {number} wa2Offset - offset for the second twiddle factors array
94-
* @returns {void}
115+
* @param {NonNegativeInteger} i - index of an element within a sub-sequence
116+
* @param {NonNegativeInteger} k - index of the sub-sequence being transformed
117+
* @param {NonNegativeInteger} j - input row
118+
* @param {NonNegativeInteger} L - number of sub-sequences
119+
* @param {NonNegativeInteger} M - sub-sequence length
120+
* @param {integer} stride - stride length of the input array
121+
* @param {NonNegativeInteger} offset - index specifying the first indexed element in the output array
122+
* @returns {NonNegativeInteger} computed index
123+
*
124+
* @example
125+
* var stride = 1;
126+
* var offset = 0;
127+
*
128+
* var M = 4; // sub-sequence length
129+
* var L = 3; // number of sub-sequences
130+
*
131+
* var idx = iptr( 0, 0, 0, L, M, stride, offset );
132+
* // returns 0
133+
*
134+
* idx = iptr( 1, 0, 0, L, M, stride, offset );
135+
* // returns 1
136+
*
137+
* idx = iptr( M-1, 0, 0, L, M, stride, offset );
138+
* // returns 3
139+
*
140+
* idx = iptr( 0, 1, 0, L, M, stride, offset );
141+
* // returns 4
142+
*
143+
* // ...
144+
*
145+
* idx = iptr( M-1, L-1, 1, L, M, stride, offset );
146+
* // returns 23
95147
*/
96-
function radf3( ido, l1, cc, ccOffset, ch, chOffset, wa1, wa1Offset, wa2, wa2Offset ) {
97-
var idp2;
98-
var tr3;
99-
var tr2;
100-
var ti3;
101-
var ti2;
102-
var dr3;
103-
var dr2;
104-
var di3;
105-
var di2;
106-
var cr2;
107-
var ci2;
108-
var ic;
109-
var i;
110-
var k;
111-
112-
// Parameter adjustments...
113-
chOffset -= 1 + ( ido << 2 );
114-
ccOffset -= 1 + ( ido * ( 1 + l1 ) );
115-
wa1Offset -= 1;
116-
wa2Offset -= 1;
117-
118-
// Function body:
119-
for ( k = 1; k <= l1; k++ ) {
120-
cr2 = cc[ ccRef( 1, k, 2, l1, ido ) + ccOffset ] + cc[ ccRef( 1, k, 3, l1, ido ) + ccOffset ];
121-
ch[ chRef( 1, 1, k, 3, ido ) + chOffset ] = cc[ ccRef( 1, k, 1, l1, ido ) + ccOffset ] + cr2;
122-
ch[ chRef( 1, 3, k, 3, ido ) + chOffset ] = taui * ( cc[ ccRef( 1, k, 3, l1, ido ) + ccOffset ] - cc[ ccRef( 1, k, 2, l1, ido ) + ccOffset ] );
123-
ch[ chRef( ido, 2, k, 3, ido ) + chOffset ] = cc[ ccRef( 1, k, 1, l1, ido ) + ccOffset ] + ( taur * cr2 );
124-
}
125-
if ( ido === 1 ) {
126-
return;
127-
}
128-
idp2 = ido + 2;
129-
for ( k = 1; k <= l1; k++ ) {
130-
for ( i = 3; i <= ido; i += 2 ) {
131-
ic = idp2 - i;
132-
dr2 = ( wa1[ i - 2 + wa1Offset ] * cc[ ccRef( i - 1, k, 2, l1, ido ) + ccOffset ]) + ( wa1[ i - 1 + wa1Offset ] * cc[ ccRef( i, k, 2, l1, ido ) + ccOffset ] );
133-
di2 = ( wa1[ i - 2 + wa1Offset ] * cc[ ccRef( i, k, 2, l1, ido ) + ccOffset ]) - ( wa1[ i - 1 + wa1Offset ] * cc[ ccRef( i - 1, k, 2, l1, ido ) + ccOffset ] );
134-
dr3 = ( wa2[ i - 2 + wa2Offset ] * cc[ ccRef( i - 1, k, 3, l1, ido ) + ccOffset ]) + ( wa2[ i - 1 + wa2Offset ] * cc[ ccRef( i, k, 3, l1, ido ) + ccOffset ] );
135-
di3 = ( wa2[ i - 2 + wa2Offset ] * cc[ ccRef( i, k, 3, l1, ido ) + ccOffset ]) - ( wa2[ i - 1 + wa2Offset ] * cc[ ccRef( i - 1, k, 3, l1, ido ) + ccOffset ] );
136-
cr2 = dr2 + dr3;
137-
ci2 = di2 + di3;
138-
ch[ chRef( i - 1, 1, k, 3, ido ) + chOffset ] = cc[ ccRef( i - 1, k, 1, l1, ido ) + ccOffset ] + cr2;
139-
ch[ chRef( i, 1, k, 3, ido ) + chOffset ] = cc[ ccRef( i, k, 1, l1, ido ) + ccOffset ] + ci2;
140-
tr2 = cc[ ccRef( i - 1, k, 1, l1, ido ) + ccOffset ] + ( taur * cr2 );
141-
ti2 = cc[ ccRef( i, k, 1, l1, ido ) + ccOffset ] + ( taur * ci2 );
142-
tr3 = taui * ( di2 - di3 );
143-
ti3 = taui * ( dr3 - dr2 );
144-
ch[ chRef( i - 1, 3, k, 3, ido ) + chOffset ] = tr2 + tr3;
145-
ch[ chRef( ic - 1, 2, k, 3, ido ) + chOffset ] = tr2 - tr3;
146-
ch[ chRef( i, 3, k, 3, ido ) + chOffset ] = ti2 + ti3;
147-
ch[ chRef( ic, 2, k, 3, ido ) + chOffset ] = ti3 - ti2;
148-
}
149-
}
148+
function iptr( i, k, j, L, M, stride, offset ) {
149+
var n = i + ( ( k+(j*L) ) * M );
150+
return ( n*stride ) + offset;
150151
}
151152

153+
/**
154+
* Resolves an index into the output array.
155+
*
156+
* ## Notes
157+
*
158+
* When writing to an output array stored in linear memory, we can reinterpret the array as a three-dimensional logical view containing `L` independent sub-sequences having three "columns" corresponding to the three components of a radix-3 stage (with real and imaginary parts interleaved along each sub-sequence) and where each "column" has `M` elements.
159+
*
160+
* Accordingly, the following is a logical view of an output array (zero-based indexing) which contains `L = 3` transforms and in which each "column" sub-sequence has length `M = 4`:
161+
*
162+
* ```text
163+
* j = 0 (component 0) j = 1 (component 1) j = 2 (component 2)
164+
* k = 0 ─┬───────────────────────────────────────┬───────────────────────────────────────┬───────────────────────────────────────┐
165+
* │ out(0,0,0) out(1,0,0) ... out(3,0,0) │ out(0,1,0) out(1,1,0) ... out(3,1,0) │ out(0,2,0) out(1,2,0) ... out(3,2,0) │
166+
* └───────────────────────────────────────┴───────────────────────────────────────┴───────────────────────────────────────┤
167+
* k = 1 ─┬───────────────────────────────────────┬───────────────────────────────────────┬───────────────────────────────────────┤
168+
* │ out(0,0,1) out(1,0,1) ... out(3,0,1) │ out(0,1,1) out(1,1,1) ... out(3,1,1) │ out(0,2,1) out(1,2,1) ... out(3,2,1) │
169+
* └───────────────────────────────────────┴───────────────────────────────────────┴───────────────────────────────────────┤
170+
* k = 2 ─┬───────────────────────────────────────┬───────────────────────────────────────┬───────────────────────────────────────┤
171+
* │ out(0,0,2) out(1,0,2) ... out(3,0,2) │ out(0,1,2) out(1,1,2) ... out(3,1,2) │ out(0,2,2) out(1,2,2) ... out(3,2,2) │
172+
* └───────────────────────────────────────┴───────────────────────────────────────┴───────────────────────────────────────┘
173+
* ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
174+
* i = 0 1 M-1 0 1 M-1 0 1 M-1
175+
* ```
176+
*
177+
* In the above,
178+
*
179+
* - `i` is the fastest varying index, which walks within one short "column" sub-sequence.
180+
* - `j` selects which of the three components we are in (0, 1, or 2).
181+
* - `k` specifies the index of one of the `L` independent transforms we are processing.
182+
*
183+
* In linear memory, the three-dimensional logical view is arranged as follows:
184+
*
185+
* ```text
186+
* | out(0,0,0)...out(3,0,0) | out(0,1,0)...out(3,1,0) | out(0,2,0)...out(3,2,0) | out(0,0,1)...out(3,0,1) | ... | out(0,2,2)...out(3,2,2) |
187+
* ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
188+
* 0 M-1 M 2M-1 2M 3M-1 3M 4M-1 (3L-1)M 3LM-1
189+
* ```
190+
*
191+
* As may be observed, when resolving an index in the output array, the `j` and `k` dimensions are swapped relative index resolution in the input array. This stems from `radf3` being only one stage in a multi-stage driver which alternates between using `cc` and `out` as workspace buffers. After each stage, the next stage reads what the previous stage wrote.
192+
*
193+
* Each stage expects a transpose, and, in order to avoid explicit transposition between the stages, we swap the last two logical dimensions while still maintaining cache locality within the inner loop logical dimension, as indexed by `i`.
194+
*
195+
* @private
196+
* @param {NonNegativeInteger} i - index of an element within a sub-sequence
197+
* @param {NonNegativeInteger} j - index specifying which of the three complex components we are in (0, 1, or 2)
198+
* @param {NonNegativeInteger} k - index of the sub-sequence being transformed
199+
* @param {NonNegativeInteger} M - sub-sequence length
200+
* @param {integer} stride - stride length of the output array
201+
* @param {NonNegativeInteger} offset - index specifying the first indexed element in the output array
202+
* @returns {NonNegativeInteger} computed index
203+
*
204+
* @example
205+
* var stride = 1;
206+
* var offset = 0;
207+
*
208+
* var M = 4; // sub-sequence length
209+
* var L = 3; // number of sub-sequences
210+
*
211+
* var idx = optr( 0, 0, 0, M, stride, offset );
212+
* // returns 0
213+
*
214+
* idx = optr( 1, 0, 0, M, stride, offset );
215+
* // returns 1
216+
*
217+
* idx = optr( M-1, 0, 0, M, stride, offset );
218+
* // returns 3
219+
*
220+
* idx = optr( 0, 1, 0, M, stride, offset );
221+
* // returns 4
222+
*
223+
* // ...
224+
*
225+
* idx = optr( M-1, 2, L-1, M, stride, offset );
226+
* // returns 35
227+
*/
228+
function optr( i, j, k, M, stride, offset ) {
229+
var n = i + ( ( j+(k*3) ) * M );
230+
return ( n*stride ) + offset;
231+
}
152232

153-
// EXPORTS //
154-
155-
module.exports = radf3;
233+
// Check diff with radf2 to see JSDoc changes

0 commit comments

Comments
 (0)