|
8 | 8 | unused_mut |
9 | 9 | )] |
10 | 10 |
|
11 | | -use std::os::raw::{c_double, c_float, c_int}; |
| 11 | +use std::{ |
| 12 | + convert::TryInto, |
| 13 | + os::raw::{c_double, c_float, c_int}, |
| 14 | +}; |
12 | 15 |
|
13 | 16 | /* ******************************************************************* |
14 | 17 | * * |
@@ -86,109 +89,77 @@ last mod: $Id: smallft.c,v 1.19 2003/10/08 05:12:37 jm Exp $ |
86 | 89 | * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the |
87 | 90 | * FORTRAN version |
88 | 91 | */ |
89 | | -unsafe extern "C" fn drfti1(wa: &mut [f32], ifac: &mut [i32]) { |
| 92 | +extern "C" fn drfti1(wa: &mut [f32], ifac: &mut [i32]) { |
| 93 | + const NTRYH: [i32; 4] = [4, 2, 3, 5]; |
| 94 | + const TPI: f32 = 6.283_185_5; |
90 | 95 |
|
91 | | - static mut ntryh: [c_int; 4] = [4 as c_int, 2 as c_int, 3 as c_int, 5 as c_int]; |
92 | | - static mut tpi: c_float = 6.28318530717958648f32; |
| 96 | + let n = wa.len().try_into().unwrap(); |
| 97 | + let ifac: &mut [i32; 32] = ifac.try_into().unwrap(); |
93 | 98 |
|
94 | | - let mut n = wa.len() as i32; |
95 | | - let mut wa = wa.as_mut_ptr(); |
96 | | - let mut ifac = ifac.as_mut_ptr(); |
| 99 | + let mut nf = 0; |
| 100 | + let mut nl = n; |
97 | 101 |
|
98 | | - let mut arg: c_float = 0.; |
99 | | - let mut argh: c_float = 0.; |
100 | | - let mut argld: c_float = 0.; |
101 | | - let mut fi: c_float = 0.; |
102 | | - let mut ntry: c_int = 0 as c_int; |
103 | | - let mut i: c_int = 0; |
104 | | - let mut j: c_int = -(1 as c_int); |
105 | | - let mut k1: c_int = 0; |
106 | | - let mut l1: c_int = 0; |
107 | | - let mut l2: c_int = 0; |
108 | | - let mut ib: c_int = 0; |
109 | | - let mut ld: c_int = 0; |
110 | | - let mut ii: c_int = 0; |
111 | | - let mut ip: c_int = 0; |
112 | | - let mut is: c_int = 0; |
113 | | - let mut nq: c_int = 0; |
114 | | - let mut nr: c_int = 0; |
115 | | - let mut ido: c_int = 0; |
116 | | - let mut ipm: c_int = 0; |
117 | | - let mut nfm1: c_int = 0; |
118 | | - let mut nl: c_int = n; |
119 | | - let mut nf: c_int = 0 as c_int; |
120 | | - 'c_10244: loop { |
121 | | - j += 1; |
122 | | - if j < 4 as c_int { |
123 | | - ntry = ntryh[j as usize] |
124 | | - } else { |
125 | | - ntry += 2 as c_int |
126 | | - } |
| 102 | + 'out: for ntry in NTRYH |
| 103 | + .iter() |
| 104 | + .copied() |
| 105 | + .chain(((NTRYH.last().unwrap() + 2)..).step_by(2)) |
| 106 | + { |
127 | 107 | loop { |
128 | | - nq = nl / ntry; |
129 | | - nr = nl - ntry * nq; |
130 | | - if nr != 0 as c_int { |
| 108 | + let nq = nl / ntry; |
| 109 | + let nr = nl - ntry * nq; |
| 110 | + if nr != 0 { |
131 | 111 | break; |
132 | 112 | } |
| 113 | + |
133 | 114 | nf += 1; |
134 | | - *ifac.offset((nf + 1 as c_int) as isize) = ntry; |
135 | | - nl = nq; |
136 | | - if !(ntry != 2 as c_int) { |
137 | | - if !(nf == 1 as c_int) { |
138 | | - i = 1 as c_int; |
139 | | - while i < nf { |
140 | | - ib = nf - i + 1 as c_int; |
141 | | - *ifac.offset((ib + 1 as c_int) as isize) = *ifac.offset(ib as isize); |
142 | | - i += 1 |
143 | | - } |
144 | | - *ifac.offset(2 as c_int as isize) = 2 as c_int |
145 | | - } |
| 115 | + ifac[nf + 1] = ntry; |
| 116 | + if ntry == 2 && nf != 1 { |
| 117 | + ifac[1..nf] |
| 118 | + .rchunks_exact_mut(2) |
| 119 | + .for_each(|chunk| chunk[1] = chunk[0]); |
| 120 | + ifac[2] = 2; |
146 | 121 | } |
147 | | - if !(nl != 1 as c_int) { |
148 | | - break 'c_10244; |
| 122 | + |
| 123 | + nl = nq; |
| 124 | + if nl == 1 { |
| 125 | + break 'out; |
149 | 126 | } |
150 | 127 | } |
151 | 128 | } |
152 | | - *ifac.offset(0 as c_int as isize) = n; |
153 | | - *ifac.offset(1 as c_int as isize) = nf; |
154 | | - argh = tpi / n as c_float; |
155 | | - is = 0 as c_int; |
156 | | - nfm1 = nf - 1 as c_int; |
157 | | - l1 = 1 as c_int; |
158 | | - if nfm1 == 0 as c_int { |
| 129 | + let nf = nf; |
| 130 | + |
| 131 | + ifac[0] = n; |
| 132 | + ifac[1] = nf.try_into().unwrap(); |
| 133 | + if nf == 0 { |
159 | 134 | return; |
160 | 135 | } |
161 | | - k1 = 0 as c_int; |
162 | | - while k1 < nfm1 { |
163 | | - ip = *ifac.offset((k1 + 2 as c_int) as isize); |
164 | | - ld = 0 as c_int; |
165 | | - l2 = l1 * ip; |
166 | | - ido = n / l2; |
167 | | - ipm = ip - 1 as c_int; |
168 | | - j = 0 as c_int; |
169 | | - while j < ipm { |
170 | | - ld += l1; |
171 | | - i = is; |
172 | | - argld = ld as c_float * argh; |
173 | | - fi = 0.0f32; |
174 | | - ii = 2 as c_int; |
175 | | - while ii < ido { |
176 | | - fi += 1.0f32; |
177 | | - arg = fi * argld; |
178 | | - let fresh0 = i; |
179 | | - i = i + 1; |
180 | | - *wa.offset(fresh0 as isize) = f64::cos(arg as c_double) as c_float; |
181 | | - let fresh1 = i; |
182 | | - i = i + 1; |
183 | | - *wa.offset(fresh1 as isize) = f64::sin(arg as c_double) as c_float; |
184 | | - ii += 2 as c_int |
185 | | - } |
186 | | - is += ido; |
187 | | - j += 1 |
188 | | - } |
189 | | - l1 = l2; |
190 | | - k1 += 1 |
191 | | - } |
| 136 | + |
| 137 | + let argh = TPI / wa.len() as f32; |
| 138 | + ifac[2..=nf] |
| 139 | + .iter() |
| 140 | + .map(|&ip| ip.try_into().unwrap()) |
| 141 | + .fold((0, 1), |(is, l1), ip: usize| { |
| 142 | + let l2 = l1 * ip; |
| 143 | + let ido = wa.len() / l2; |
| 144 | + let ipm = ip - 1; |
| 145 | + |
| 146 | + wa[is..] |
| 147 | + .chunks_exact_mut(ido) |
| 148 | + .zip((l1..).step_by(l1).map(|ld| ld as f32 * argh)) |
| 149 | + .take(ipm) |
| 150 | + .for_each(|(chunk, argld)| { |
| 151 | + chunk[..(ido - 2).try_into().unwrap_or(0)] |
| 152 | + .chunks_exact_mut(2) |
| 153 | + .fold(1f32, |fi, chunk| { |
| 154 | + let arg = (fi * argld) as f64; |
| 155 | + chunk[0] = f64::cos(arg) as f32; |
| 156 | + chunk[1] = f64::sin(arg) as f32; |
| 157 | + fi + 1. |
| 158 | + }); |
| 159 | + }); |
| 160 | + |
| 161 | + (is + ipm * ido, l2) |
| 162 | + }); |
192 | 163 | } |
193 | 164 | unsafe extern "C" fn fdrffti(n: usize, wsave: &mut [f32], mut ifac: &mut [i32]) { |
194 | 165 | if n == 1 { |
|
0 commit comments