Created
January 13, 2017 07:09
-
-
Save friedbrice/ea27eec02bc58b2417329e5e4a162078 to your computer and use it in GitHub Desktop.
Work These Days
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def fourier_series(n, samples): | |
""" | |
`fourier_series` | |
From a list of `samples` taken from an unknown periodic function, | |
returns the best-fit `n`-term sine/cosine approximation of the | |
unknown function. | |
Args: | |
param1 (int): The number of terms you want in your | |
approximation. | |
param2 (list): The list of samples from your unknown periodic | |
function. | |
Returns: | |
(list): The return value. List of 3-tuples of numbers, where the | |
first entry is the frequency, the second entry is the | |
coefficient of cosine, and the third entry is the coefficient of | |
sine. | |
Contract: | |
- `samples` must be drawn from a (presumably unknown) periodic | |
function of time. | |
- The `samples` must be given in increasing chronological order. | |
- The time interval between samples must be constant. | |
- The number of samples must be an integer multiple of a full | |
period. No Fractions of Periods Allowed. | |
`fourier_series`s return is only meaningful if the contract is met. | |
If you fail to meet the contract, the algorithm won't complain, but | |
it will return what appears to be a coherent result that is actually | |
Total Shit, leading to grossly-inaccurate forcasts. | |
""" | |
import cmath | |
import heapq | |
from numpy import fft | |
s = len(samples) | |
freq_domain = zip(range(1, s + 1), fft.fft(samples)) | |
modulus = lambda p: cmath.polar(p[1])[0] | |
scale = lambda p: (p[0], p[1].real / s, p[1].imag / s) | |
series = map(scale, heapq.nlargest(n, freq_domain, modulus)) | |
return list(series) | |
def eval_series(series, t): | |
""" | |
`eval_series` | |
Find the value of the given Fourier `series` at the argument `t`. | |
Args: | |
param1 (list): A list of 3-tuples that represents the Fourier | |
series where the first entries are the | |
frequencies, the second entries are the | |
coefficients of cosine, and the third entries are | |
the coefficients of sine. | |
param2 (double): The argument `t` to the Fourier `series`. | |
Return: | |
(double): The value of the Fourier `series` at the argument `t`. | |
""" | |
import math | |
cosf = lambda frq, amp, t: amp * math.cos(frq * 2 * math.pi * t) | |
sinf = lambda frq, amp, t: amp * math.sin(frq * 2 * math.pi * t) | |
opr = lambda tup: cosf(tup[0], tup[1], t) + sinf(tup[0], tup[2], t) | |
return sum(map(opr, series)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment