Spaces:
Sleeping
Sleeping
File size: 5,891 Bytes
6a86ad5 |
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 |
from sympy.core.add import Add
from sympy.core.numbers import (Rational, oo, pi)
from sympy.core.singleton import S
from sympy.core.symbol import symbols
from sympy.functions.elementary.exponential import (exp, log)
from sympy.functions.elementary.piecewise import Piecewise
from sympy.functions.elementary.trigonometric import (cos, sin, sinc, tan)
from sympy.series.fourier import fourier_series
from sympy.series.fourier import FourierSeries
from sympy.testing.pytest import raises
from functools import lru_cache
x, y, z = symbols('x y z')
# Don't declare these during import because they are slow
@lru_cache()
def _get_examples():
fo = fourier_series(x, (x, -pi, pi))
fe = fourier_series(x**2, (-pi, pi))
fp = fourier_series(Piecewise((0, x < 0), (pi, True)), (x, -pi, pi))
return fo, fe, fp
def test_FourierSeries():
fo, fe, fp = _get_examples()
assert fourier_series(1, (-pi, pi)) == 1
assert (Piecewise((0, x < 0), (pi, True)).
fourier_series((x, -pi, pi)).truncate()) == fp.truncate()
assert isinstance(fo, FourierSeries)
assert fo.function == x
assert fo.x == x
assert fo.period == (-pi, pi)
assert fo.term(3) == 2*sin(3*x) / 3
assert fe.term(3) == -4*cos(3*x) / 9
assert fp.term(3) == 2*sin(3*x) / 3
assert fo.as_leading_term(x) == 2*sin(x)
assert fe.as_leading_term(x) == pi**2 / 3
assert fp.as_leading_term(x) == pi / 2
assert fo.truncate() == 2*sin(x) - sin(2*x) + (2*sin(3*x) / 3)
assert fe.truncate() == -4*cos(x) + cos(2*x) + pi**2 / 3
assert fp.truncate() == 2*sin(x) + (2*sin(3*x) / 3) + pi / 2
fot = fo.truncate(n=None)
s = [0, 2*sin(x), -sin(2*x)]
for i, t in enumerate(fot):
if i == 3:
break
assert s[i] == t
def _check_iter(f, i):
for ind, t in enumerate(f):
assert t == f[ind]
if ind == i:
break
_check_iter(fo, 3)
_check_iter(fe, 3)
_check_iter(fp, 3)
assert fo.subs(x, x**2) == fo
raises(ValueError, lambda: fourier_series(x, (0, 1, 2)))
raises(ValueError, lambda: fourier_series(x, (x, 0, oo)))
raises(ValueError, lambda: fourier_series(x*y, (0, oo)))
def test_FourierSeries_2():
p = Piecewise((0, x < 0), (x, True))
f = fourier_series(p, (x, -2, 2))
assert f.term(3) == (2*sin(3*pi*x / 2) / (3*pi) -
4*cos(3*pi*x / 2) / (9*pi**2))
assert f.truncate() == (2*sin(pi*x / 2) / pi - sin(pi*x) / pi -
4*cos(pi*x / 2) / pi**2 + S.Half)
def test_square_wave():
"""Test if fourier_series approximates discontinuous function correctly."""
square_wave = Piecewise((1, x < pi), (-1, True))
s = fourier_series(square_wave, (x, 0, 2*pi))
assert s.truncate(3) == 4 / pi * sin(x) + 4 / (3 * pi) * sin(3 * x) + \
4 / (5 * pi) * sin(5 * x)
assert s.sigma_approximation(4) == 4 / pi * sin(x) * sinc(pi / 4) + \
4 / (3 * pi) * sin(3 * x) * sinc(3 * pi / 4)
def test_sawtooth_wave():
s = fourier_series(x, (x, 0, pi))
assert s.truncate(4) == \
pi/2 - sin(2*x) - sin(4*x)/2 - sin(6*x)/3
s = fourier_series(x, (x, 0, 1))
assert s.truncate(4) == \
S.Half - sin(2*pi*x)/pi - sin(4*pi*x)/(2*pi) - sin(6*pi*x)/(3*pi)
def test_FourierSeries__operations():
fo, fe, fp = _get_examples()
fes = fe.scale(-1).shift(pi**2)
assert fes.truncate() == 4*cos(x) - cos(2*x) + 2*pi**2 / 3
assert fp.shift(-pi/2).truncate() == (2*sin(x) + (2*sin(3*x) / 3) +
(2*sin(5*x) / 5))
fos = fo.scale(3)
assert fos.truncate() == 6*sin(x) - 3*sin(2*x) + 2*sin(3*x)
fx = fe.scalex(2).shiftx(1)
assert fx.truncate() == -4*cos(2*x + 2) + cos(4*x + 4) + pi**2 / 3
fl = fe.scalex(3).shift(-pi).scalex(2).shiftx(1).scale(4)
assert fl.truncate() == (-16*cos(6*x + 6) + 4*cos(12*x + 12) -
4*pi + 4*pi**2 / 3)
raises(ValueError, lambda: fo.shift(x))
raises(ValueError, lambda: fo.shiftx(sin(x)))
raises(ValueError, lambda: fo.scale(x*y))
raises(ValueError, lambda: fo.scalex(x**2))
def test_FourierSeries__neg():
fo, fe, fp = _get_examples()
assert (-fo).truncate() == -2*sin(x) + sin(2*x) - (2*sin(3*x) / 3)
assert (-fe).truncate() == +4*cos(x) - cos(2*x) - pi**2 / 3
def test_FourierSeries__add__sub():
fo, fe, fp = _get_examples()
assert fo + fo == fo.scale(2)
assert fo - fo == 0
assert -fe - fe == fe.scale(-2)
assert (fo + fe).truncate() == 2*sin(x) - sin(2*x) - 4*cos(x) + cos(2*x) \
+ pi**2 / 3
assert (fo - fe).truncate() == 2*sin(x) - sin(2*x) + 4*cos(x) - cos(2*x) \
- pi**2 / 3
assert isinstance(fo + 1, Add)
raises(ValueError, lambda: fo + fourier_series(x, (x, 0, 2)))
def test_FourierSeries_finite():
assert fourier_series(sin(x)).truncate(1) == sin(x)
# assert type(fourier_series(sin(x)*log(x))).truncate() == FourierSeries
# assert type(fourier_series(sin(x**2+6))).truncate() == FourierSeries
assert fourier_series(sin(x)*log(y)*exp(z),(x,pi,-pi)).truncate() == sin(x)*log(y)*exp(z)
assert fourier_series(sin(x)**6).truncate(oo) == -15*cos(2*x)/32 + 3*cos(4*x)/16 - cos(6*x)/32 \
+ Rational(5, 16)
assert fourier_series(sin(x) ** 6).truncate() == -15 * cos(2 * x) / 32 + 3 * cos(4 * x) / 16 \
+ Rational(5, 16)
assert fourier_series(sin(4*x+3) + cos(3*x+4)).truncate(oo) == -sin(4)*sin(3*x) + sin(4*x)*cos(3) \
+ cos(4)*cos(3*x) + sin(3)*cos(4*x)
assert fourier_series(sin(x)+cos(x)*tan(x)).truncate(oo) == 2*sin(x)
assert fourier_series(cos(pi*x), (x, -1, 1)).truncate(oo) == cos(pi*x)
assert fourier_series(cos(3*pi*x + 4) - sin(4*pi*x)*log(pi*y), (x, -1, 1)).truncate(oo) == -log(pi*y)*sin(4*pi*x)\
- sin(4)*sin(3*pi*x) + cos(4)*cos(3*pi*x)
|