-
Notifications
You must be signed in to change notification settings - Fork 6
/
poincare.py
92 lines (80 loc) · 2.59 KB
/
poincare.py
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
###############################################################################
#
# CSCI 4446 - Chaotic Dynamics
#
# File: poincare.py
# Author: Ken Sheedlo
#
# Poincare section taker, PS6 stuff
#
###############################################################################
from __future__ import division
import chaostest
import getopt
import numpy
import plot
import rungekutta
import sys
import unittest
def section(ts, xs, interval=1.0, t_start=0.0):
'''
Simple, stupid Poincare section routine.
'''
t_final = ts[-1]
p_ct = int((t_final+interval - t_start) / interval)
ps = t_start + numpy.array(range(p_ct+1), dtype=numpy.float64) * interval
i = 0
j = 0
points = numpy.empty((len(xs), xs[0].size), dtype=numpy.float64)
for (ti, tj, x) in zip(ts[:-1], ts[1:], xs[1:]):
while ps[i] < ti and i <= p_ct:
i += 1
if i > p_ct:
break
if ti < ps[i] and ps[i] <= tj:
points[j] = x
j += 1
return points[:j]
def linear(ts, xs, interval=1.0, t_start=0.0):
'''
Slightly smarter section routine, that linear interpolate frobs.
'''
t_final = ts[-1]
p_ct = int((t_final+interval - t_start) / interval)
ps = t_start + numpy.array(range(p_ct+1), dtype=numpy.float64) * interval
i = 0
j = 0
points = numpy.empty((len(xs), xs[0].size), dtype=numpy.float64)
for (ti, tj, xi, xj) in zip(ts[:-1], ts[1:], xs[:-1], xs[1:]):
while ps[i] < ti and i <= p_ct:
i += 1
if i > p_ct:
break
if ti < ps[i] and ps[i] <= tj:
dx = xj - xi
points[j] = xi + dx*(ps[i]-ti)/(tj-ti)
j += 1
return points[:j]
class TestPoincare(chaostest.TestCase):
'''
Unit tests for Poincare section routines.
'''
def test_section(self):
'''
Tests the simple section routine with normal input.
'''
xs = numpy.array([1, 2, 42, 99, 1337, 23], dtype=numpy.float64)
ts = numpy.array([1, 2, 3, 4, 5, 6], dtype=numpy.float64)
ps = section(ts, xs, interval=2.0, t_start=1.5)
self.assertArrayEqual(ps, xs[1::2])
def test_linear(self):
'''
Tests the linear section routine with normal input.
'''
xs = numpy.array([1, 2, 42, 99, 1337, 23], dtype=numpy.float64)
ts = numpy.array([1, 2, 3, 4, 5, 6], dtype=numpy.float64)
ps = linear(ts, xs, interval=2.0, t_start=1.5)
expected = numpy.array([1.5, 70.5, 680.0], dtype=numpy.float64)
self.assertArrayEqual(ps, expected)
if __name__ == "__main__":
unittest.main()