1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
/* fft/factorize.c
*
* Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <config.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_fft_complex.h>
#include "factorize.h"
static int
fft_complex_factorize (const size_t n,
size_t *nf,
size_t factors[])
{
const size_t complex_subtransforms[] =
{7, 6, 5, 4, 3, 2, 0};
/* other factors can be added here if their transform modules are
implemented. The end of the list is marked by 0. */
int status = fft_factorize (n, complex_subtransforms, nf, factors);
return status;
}
static int
fft_halfcomplex_factorize (const size_t n,
size_t *nf,
size_t factors[])
{
const size_t halfcomplex_subtransforms[] =
{5, 4, 3, 2, 0};
int status = fft_factorize (n, halfcomplex_subtransforms, nf, factors);
return status;
}
static int
fft_real_factorize (const size_t n,
size_t *nf,
size_t factors[])
{
const size_t real_subtransforms[] =
{5, 4, 3, 2, 0};
int status = fft_factorize (n, real_subtransforms, nf, factors);
return status;
}
static int
fft_factorize (const size_t n,
const size_t implemented_subtransforms[],
size_t *n_factors,
size_t factors[])
{
size_t nf = 0;
size_t ntest = n;
size_t factor;
size_t i = 0;
if (n == 0)
{
GSL_ERROR ("length n must be positive integer", GSL_EDOM);
}
if (n == 1)
{
factors[0] = 1;
*n_factors = 1;
return 0;
}
/* deal with the implemented factors first */
while (implemented_subtransforms[i] && ntest != 1)
{
factor = implemented_subtransforms[i];
while ((ntest % factor) == 0)
{
ntest = ntest / factor;
factors[nf] = factor;
nf++;
}
i++;
}
/* deal with any other even prime factors (there is only one) */
factor = 2;
while ((ntest % factor) == 0 && (ntest != 1))
{
ntest = ntest / factor;
factors[nf] = factor;
nf++;
}
/* deal with any other odd prime factors */
factor = 3;
while (ntest != 1)
{
while ((ntest % factor) != 0)
{
factor += 2;
}
ntest = ntest / factor;
factors[nf] = factor;
nf++;
}
/* check that the factorization is correct */
{
size_t product = 1;
for (i = 0; i < nf; i++)
{
product *= factors[i];
}
if (product != n)
{
GSL_ERROR ("factorization failed", GSL_ESANITY);
}
}
*n_factors = nf;
return 0;
}
static int
fft_binary_logn (const size_t n)
{
size_t ntest ;
size_t binary_logn = 0 ;
size_t k = 1;
while (k < n)
{
k *= 2;
binary_logn++;
}
ntest = (1 << binary_logn) ;
if (n != ntest )
{
return -1 ; /* n is not a power of 2 */
}
return binary_logn;
}
|