Skip to content

Commit 3195757

Browse files
committed
feat: add fft/base/fftpack/rffti
1 parent 13cf096 commit 3195757

15 files changed

Lines changed: 1532 additions & 0 deletions

File tree

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2026 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# rffti
22+
23+
> Initialize a workspace array for performing a real-valued Fourier transform.
24+
25+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
26+
27+
<section class="intro">
28+
29+
</section>
30+
31+
<!-- /.intro -->
32+
33+
<!-- Package usage documentation. -->
34+
35+
<section class="usage">
36+
37+
## Usage
38+
39+
```javascript
40+
var rffti = require( '@stdlib/fft/base/fftpack/rffti' );
41+
```
42+
43+
#### rffti( N, workspace, strideW, offsetW )
44+
45+
Initializes a workspace array for performing a real-valued Fourier transform.
46+
47+
```javascript
48+
var Float64Array = require( '@stdlib/array/float64' );
49+
50+
var N = 8;
51+
var workspace = new Float64Array( ( 2*N ) + 34 );
52+
53+
rffti( N, workspace, 1, 0 );
54+
55+
var twiddleFactors = workspace.slice( N, 2*N );
56+
// returns <Float64Array>[ 0, ~0.707, ~0.707, 0, 0, 0, 0, 0 ]
57+
58+
var factors = workspace.slice( 2*N, ( 2*N ) + 4 );
59+
// returns <Float64Array>[ 8, 2, 2, 4 ]
60+
```
61+
62+
The function accepts the following arguments:
63+
64+
- **N**: length of the sequence to transform.
65+
- **workspace**: workspace array.
66+
- **strideW**: stride length for `workspace`.
67+
- **offsetW**: starting index for `workspace`.
68+
69+
</section>
70+
71+
<!-- /.usage -->
72+
73+
<!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
74+
75+
<section class="notes">
76+
77+
## Notes
78+
79+
- The workspace array is divided into three sections:
80+
81+
```text
82+
size = N N 2+ceil(log2(N)/2)
83+
↓ ↓ ↓
84+
| scratch / workspace | twiddle factors | radix factor table |
85+
↑ ↑ ↑
86+
i = 0 ... N ... 2N ...
87+
```
88+
89+
- **scratch/workspace**: used as a scratch space when performing transforms. This section is not updated during initialization.
90+
- **twiddle factors**: a table of reusable complex-exponential constants stored as cosine/sine pairs.
91+
- **radix factor table**: a table containing the sequence length `N`, the number of factors into which `N` was decomposed, and the individual integer radix factors.
92+
93+
- In general, a workspace array should have `2N + 34` indexed elements (as `log2(N)/2 ≤ 32` for all `2^64`). During initialization, only the sections for storing twiddle factors and the factorization of `N` are updated.
94+
95+
- The radix factor table is comprised as follows:
96+
97+
```text
98+
| sequence_length | number_of_factors | integer_factors |
99+
```
100+
101+
- If `N` equals `1`, the function returns early without modifying the workspace, as a single data point is its own Fourier transform.
102+
103+
</section>
104+
105+
<!-- /.notes -->
106+
107+
<section class="examples">
108+
109+
## Examples
110+
111+
<!-- eslint no-undef: "error" -->
112+
113+
```javascript
114+
var Float64Array = require( '@stdlib/array/float64' );
115+
var rffti = require( '@stdlib/fft/base/fftpack/rffti' );
116+
117+
var workspace;
118+
var N;
119+
var nf;
120+
var i;
121+
var j;
122+
123+
N = 8;
124+
workspace = new Float64Array( ( 2*N ) + 34 );
125+
126+
rffti( N, workspace, 1, 0 );
127+
128+
console.log( 'Sequence length: %d', N );
129+
console.log( 'Twiddle factors:' );
130+
for ( i = N; i < 2*N; i++ ) {
131+
console.log( ' workspace[%d] = %d', i, workspace[ i ] );
132+
}
133+
134+
console.log( 'Factorization:' );
135+
nf = workspace[ ( 2*N ) + 1 ];
136+
console.log( ' number of factors: %d', nf );
137+
for ( j = 0; j < nf; j++ ) {
138+
console.log( ' factor[%d]: %d', j, workspace[ ( 2*N ) + 2 + j ] );
139+
}
140+
```
141+
142+
</section>
143+
144+
<!-- /.examples -->
145+
146+
<!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
147+
148+
<section class="references">
149+
150+
</section>
151+
152+
<!-- /.references -->
153+
154+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
155+
156+
<section class="related">
157+
158+
</section>
159+
160+
<!-- /.related -->
161+
162+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
163+
164+
<section class="links">
165+
166+
</section>
167+
168+
<!-- /.links -->
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var bench = require( '@stdlib/bench' );
24+
var format = require( '@stdlib/string/format' );
25+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
26+
var Float64Array = require( '@stdlib/array/float64' );
27+
var pkg = require( './../package.json' ).name;
28+
var rffti = require( './../lib' );
29+
30+
31+
// FUNCTIONS //
32+
33+
/**
34+
* Creates a benchmark function.
35+
*
36+
* @private
37+
* @param {PositiveInteger} N - sequence length
38+
* @returns {Function} benchmark function
39+
*/
40+
function createBenchmark( N ) {
41+
var workspace = new Float64Array( ( 2*N ) + 34 );
42+
return benchmark;
43+
44+
/**
45+
* Benchmark function.
46+
*
47+
* @private
48+
* @param {Benchmark} b - benchmark instance
49+
*/
50+
function benchmark( b ) {
51+
var i;
52+
53+
b.tic();
54+
for ( i = 0; i < b.iterations; i++ ) {
55+
rffti( N, workspace, 1, 0 );
56+
if ( isnan( workspace[ N+1 ] ) ) {
57+
b.fail( 'should not return NaN' );
58+
}
59+
}
60+
b.toc();
61+
if ( isnan( workspace[ N+1 ] ) ) {
62+
b.fail( 'should not return NaN' );
63+
}
64+
b.pass( 'benchmark finished' );
65+
b.end();
66+
}
67+
}
68+
69+
70+
// MAIN //
71+
72+
/**
73+
* Main execution sequence.
74+
*
75+
* @private
76+
*/
77+
function main() {
78+
var lengths;
79+
var N;
80+
var f;
81+
var i;
82+
83+
lengths = [
84+
8,
85+
16,
86+
32,
87+
64,
88+
128,
89+
256,
90+
512,
91+
1024
92+
];
93+
94+
for ( i = 0; i < lengths.length; i++ ) {
95+
N = lengths[ i ];
96+
f = createBenchmark( N );
97+
bench( format( '%s:N=%d', pkg, N ), f );
98+
}
99+
}
100+
101+
main();
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
{{alias}}( N, workspace, strideW, offsetW )
3+
Initializes a workspace array for performing a real-valued Fourier
4+
transform.
5+
6+
The workspace array is divided into three sections: scratch/workspace
7+
(indices 0 to N-1), twiddle factors (indices N to 2N-1), and radix factor
8+
table (indices 2N onwards).
9+
10+
The scratch/workspace section is used while performing transforms and is
11+
not updated during initialization. The twiddle factors section stores a
12+
table of reusable complex exponential constants as cosine/sine pairs. The
13+
radix factor table stores the sequence length N, the number of factors into
14+
which N was decomposed, and the individual integer radix factors.
15+
16+
Any remaining array space remains as unused storage.
17+
18+
Parameters
19+
----------
20+
N: integer
21+
Length of the sequence.
22+
23+
workspace: ArrayLikeObject<number>
24+
Workspace array.
25+
26+
strideW: integer
27+
Stride length for `workspace`.
28+
29+
offsetW: integer
30+
Starting index for `workspace`.
31+
32+
Examples
33+
--------
34+
> var {{alias:@stdlib/array/float64}} = require( '@stdlib/array/float64' );
35+
> var N = 8;
36+
> var workspace = new {{alias:@stdlib/array/float64}}( ( 2*N ) + 34 );
37+
> {{alias}}( N, workspace, 1, 0 );
38+
> var twiddleFactors = workspace.slice( N, 2*N )
39+
<Float64Array>[ 0, ~0.707, ~0.707, 0, 0, 0, 0, 0 ]
40+
> var factors = workspace.slice( 2*N, ( 2*N ) + 4 )
41+
<Float64Array>[ 8, 2, 2, 4 ]
42+
43+
See Also
44+
--------
45+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
// TypeScript Version: 4.1
20+
21+
/// <reference types="@stdlib/types"/>
22+
23+
import { Collection } from '@stdlib/types/array';
24+
25+
/**
26+
* Initializes a workspace array for performing a real-valued Fourier transform.
27+
*
28+
* @param N - length of the sequence
29+
* @param workspace - workspace array
30+
* @param strideW - stride length for `workspace`
31+
* @param offsetW - starting index for `workspace`
32+
*
33+
* @example
34+
* var Float64Array = require( '@stdlib/array/float64' );
35+
* var N = 8;
36+
* var workspace = new Float64Array( ( 2*N ) + 34 );
37+
*
38+
* rffti( N, workspace, 1, 0 );
39+
*
40+
* var twiddleFactors = workspace.slice( N, 2*N );
41+
* // returns <Float64Array>[ 0, ~0.707, ~0.707, 0, 0, 0, 0, 0 ]
42+
*
43+
* var factors = workspace.slice( 2*N, ( 2*N ) + 4 );
44+
* // returns <Float64Array>[ 8, 2, 2, 4 ]
45+
*/
46+
declare function rffti( N: number, workspace: Collection<number>, strideW: number, offsetW: number ): void;
47+
48+
49+
// EXPORTS //
50+
51+
export = rffti;

0 commit comments

Comments
 (0)