Skip to content
Snippets Groups Projects
Commit f21a817b authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

docs

parent b5b3a73b
No related branches found
No related tags found
No related merge requests found
......@@ -61,7 +61,6 @@ instance/
# Scrapy stuff:
.scrapy
docs/
# Sphinx documentation
docs/_build/
......
......@@ -30,6 +30,9 @@ slice them and so on.
## Series
Can be imported from _sai.series_. A generic abstract superclass for series -
`Series` can be imported for checking if given object is a series.
### DiscreteSeries
To use a _DiscreteSeries_ you must give it a set of data to work with. These
......@@ -57,6 +60,17 @@ fs[6] == 6
Although you can't specify a domain where it would be impossible to compute the value.
(ie. starting at smaller than zero). Doing so will throw a _ValueError_.
Note that when using `join_discrete()` sometimes other series might get calls
from beyond their domain. This can be seen for example here:
```python
logs = FunctionSeries(math.log, '(0;5>')
dirs = DiscreteSeries([(0,1)], '<0;5>')
# Raises ValueError due to math.log being called with 0
dirs.join_discrete(logs, lambda x, y: x+y)
```
### FunctionSeries
Using _FunctionSeries_ is straightforward. Just give them a callable and
......@@ -66,12 +80,23 @@ a domain:
fs = FunctionSeries(lambda x: x**2, '<-2;2>')
```
## Ranges
### ModuloSeries
_ModuloSeries_ allow you to wrap a finite series in repetition.
```python
from firanka.series import Range
fs = ModuloSeries(someOtherSeries)
```
By definition, _ModuloSeries_ has the domain of all real numbers.
Note that someOtherSeries's domain length must be non-zero and finite. Otherwise
_ValueError_ will be thrown.
## Ranges
Can be imported from _sai.series_.
Range would have been better called an **interval**. It is a continuous subset
of the real number line.
......
......@@ -2,8 +2,7 @@
# coding=UTF-8
from __future__ import print_function, absolute_import, division
import six
import functools
import itertools
import math
from .range import Range, REAL_SET, EMPTY_RANGE
from .exceptions import NotInDomainError
......@@ -153,7 +152,6 @@ class DiscreteSeries(Series):
if self.domain.start < data[0][0]:
raise ValueError('some domain space is not covered by definition!')
def apply(self, fun):
return DiscreteSeries([(k, fun(v)) for k, v in self.data], self.domain)
......@@ -265,6 +263,11 @@ class JoinedSeries(Series):
class ModuloSeries(Series):
def __init__(self, series):
"""
Construct a modulo series
:param series: base series to use
:raise ValueError: invalid domain length
"""
super(ModuloSeries, self).__init__(REAL_SET)
self.series = series
......@@ -272,6 +275,8 @@ class ModuloSeries(Series):
if self.period == 0:
raise ValueError('Modulo series cannot have a period of 0')
elif math.isinf(self.period):
raise ValueError('Modulo series cannot have an infinite period')
def _get_for(self, item):
if item < 0:
......
# coding=UTF-8
from __future__ import print_function, absolute_import, division
import six
import math
import unittest
from firanka.series import DiscreteSeries, FunctionSeries, Range, ModuloSeries, NotInDomainError
NOOP = lambda x: x
class TestDiscreteSeries(unittest.TestCase):
......@@ -63,7 +65,7 @@ class TestDiscreteSeries(unittest.TestCase):
def test_eval2(self):
sa = DiscreteSeries([[0, 0], [1, 1], [2, 2]])
sb = FunctionSeries(lambda x: x, '<0;2>')
sb = FunctionSeries(NOOP, '<0;2>')
sc = sa.join_discrete(sb, lambda a, b: a+b)
self.assertEqual(sc.eval_points([0,1,2]), [0,2,4])
......@@ -77,7 +79,7 @@ class TestDiscreteSeries(unittest.TestCase):
def test_eval3(self):
sa = FunctionSeries(lambda x: x**2, '<-10;10)')
sb = FunctionSeries(lambda x: x, '<0;2)')
sb = FunctionSeries(NOOP, '<0;2)')
sc = sa.join(sb, lambda a, b: a*b)
......@@ -104,9 +106,10 @@ class TestDiscreteSeries(unittest.TestCase):
empty = FunctionSeries(lambda x: x**2, '<-10;10)').discretize([])
self.assertTrue(empty.domain.is_empty())
class TestFunctionSeries(unittest.TestCase):
def test_slice(self):
series = FunctionSeries(lambda x: x, '<0;2>')
series = FunctionSeries(NOOP, '<0;2>')
sp = series[0.5:1.5]
self.assertEqual(sp[0.5], 0.5)
......@@ -118,11 +121,23 @@ class TestFunctionSeries(unittest.TestCase):
def test_apply(self):
PTS = [-1,-2,-3,1,2,3]
series = FunctionSeries(lambda x: x, '<-5;5>').apply(lambda x: x*2)
series = FunctionSeries(NOOP, '<-5;5>').apply(lambda x: x*2)
self.assertEqual(series.eval_points(PTS), [x*2 for x in PTS])
def test_domain_sensitivity(self):
logs = FunctionSeries(math.log, '(0;5>')
dirs = DiscreteSeries([(0,1),(1,2),(3,4)], '<0;5>')
self.assertRaises(ValueError, lambda: dirs.join_discrete(logs, lambda x, y: x+y))
class TestModuloSeries(unittest.TestCase):
def test_exceptions(self):
self.assertRaises(ValueError, lambda: ModuloSeries(FunctionSeries(NOOP, '(-inf; 0>')))
self.assertRaises(ValueError, lambda: ModuloSeries(FunctionSeries(NOOP, '(-inf; inf)')))
self.assertRaises(ValueError, lambda: ModuloSeries(FunctionSeries(NOOP, '<0; 0>')))
def test_base(self):
series = ModuloSeries(DiscreteSeries([(0,1),(1,2),(2,3)], '<0;3)'))
......@@ -133,7 +148,7 @@ class TestModuloSeries(unittest.TestCase):
def test_comp_discrete(self):
ser1 = ModuloSeries(FunctionSeries(lambda x: x**2, '<0;3)'))
ser2 = FunctionSeries(lambda x: x, '<0;3)')
ser2 = FunctionSeries(NOOP, '<0;3)')
ser3 = ser1.join(ser2, lambda x, y: x*y)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment