General programming: logical FFT OR high-precision convolution (python)

I have a slightly unusual problem, but I try to avoid re-encoding FFT.

In general, I want to know is: If I have an algorithm implemented for the type float, but it will work wherever a certain defined set of operations (such as complex numbers, which are also defined +, *...), what is the best way to use this algorithm for another type that supports these operations? In practice, this is difficult because, in general, numerical algorithms are written for speed, and not for generality.

In particular:
I work with values ​​with a very high dynamic range, so I would like to store them in the log space (mainly to avoid underutilization).

I would like the FFT magazine of some series:

x = [1,2,3,4,5]
fft_x = [ log( x_val ) for x_val in fft(x) ]

Even this will lead to a significant decrease. I would like to store log values ​​and use +instead *and logaddexpinstead +, etc.

My thought on how to do this is to implement a simple LogFloat class that defines these primitive operations (but works in the log space). Then I could just run the FFT code, allowing my registered values ​​to be used.

class LogFloat:
    def __init__(self, sign, log_val):
        assert(float(sign) in (-1, 1))
        self.sign = int(sign)
        self.log_val = log_val
    @staticmethod
    def from_float(fval):
        return LogFloat(sign(fval), log(abs(fval)))
    def __imul__(self, lf):
        self.sign *= lf.sign
        self.log_val += lf.log_val
        return self
    def __idiv__(self, lf):
        self.sign *= lf.sign
        self.log_val -= lf.log_val
        return self
    def __iadd__(self, lf):
        if self.sign == lf.sign:
            self.log_val = logaddexp(self.log_val, lf.log_val)
        else:
            # subtract the smaller magnitude from the larger
            if self.log_val > lf.log_val:
                self.log_val = log_sub(self.log_val, lf.log_val)
            else:
                self.log_val = log_sub(lf.log_val, self.log_val)
                self.sign *= -1
        return self
    def __isub__(self, lf):
        self.__iadd__(LogFloat(-1 * lf.sign, lf.log_val))
        return self
    def __pow__(self, lf):
        # note: there may be a way to do this without exponentiating
        # if the exponent is 0, always return 1
#        print self, '**', lf
        if lf.log_val == -float('inf'):
            return LogFloat.from_float(1.0)
        lf_value = lf.sign * math.exp(lf.log_val)
        if self.sign == -1:
            # note: in this case, lf_value must be an integer
            return LogFloat(self.sign**int(lf_value), self.log_val * lf_value)
        return LogFloat(self.sign, self.log_val * lf_value)
    def __mul__(self, lf):
        temp = LogFloat(self.sign, self.log_val)
        temp *= lf
        return temp
    def __div__(self, lf):
        temp = LogFloat(self.sign, self.log_val)
        temp /= lf
        return temp
    def __add__(self, lf):
        temp = LogFloat(self.sign, self.log_val)
        temp += lf
        return temp
    def __sub__(self, lf):
        temp = LogFloat(self.sign, self.log_val)
        temp -= lf
        return temp
    def __str__(self):
        result = str(self.sign * math.exp(self.log_val)) + '('
        if self.sign == -1:
            result += '-'
        result += 'e^' + str(self.log_val) + ')'
        return result
    def __neg__(self):
        return LogFloat(-self.sign, self.log_val)
    def __radd__(self, val):
        # for sum
        if val == 0:
            return self
        return self + val

Then the idea would be to create a list LogFloats and then use it in FFT:

x_log_float = [ LogFloat.from_float(x_val) for x_val in x ]
fft_x_log_float = fft(x_log_float)

, FFT ( LogFloat, float, , . : , ( , "+", "-", "," /" ..).

, , .. . exmaple, , ( , ).

, , FFT , . , , , ...

, , - , ( N ^ 2 ). .

* . , LogFloat, .

EDIT: , LogFloat - ( LogFloat). - , @JFSebastian Python, ( DSP, Wikipedia).

+5
2

, ​​ . , : ( ) . , , , , - . , Python. Python 2 Python 3. , . Python IBM/IEEE . Python 3.3 ( -, - ), C 100 ( ).

+1

s, , ,

F (f (t)) = X (j * w)

F (s f (s * t)) ↔ X (w/s)

, , , , .

0

All Articles