Skip to content
Snippets Groups Projects
Piotr Maslanka's avatar
Piotr Maślanka authored
f21a817b

firanka

Build Status Maintainability Test Coverage PyPI version PyPI PyPI PyPI license

firanka is a Python library to perform calculations on particular kinds of functions. These functions have a domain, which is a single continuous subset of the real number line. These functions can have any values.

firanka allows you do define two classes of such functions or series.

First are the DiscreteSeries. DiscreteSeries further divide the function domain into slices (left-closed, right-open) that have constant values. Manipulating DiscreteSeries and performing calculations on them is cheap.

Then you have FunctionSeries. These are simply defined by user-supplied Python callable.

Best part is, you can join series together (given a joining operator), slice them and so on.

Usage

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 will define intervals, left-closed, right-open. Ie.

fs = DiscreteSeries([(0,1), (3, 4), (5, 6)])
fs[0.5] == 1
fs[3] == 4
fs[5] == 6
# fs[6] - NotInDomainError's

Datapoints given must be already sorted!. By default, the domain will be both sides closed, from minimum to maximum given in data, but you can specify a custom one:

fs = DiscreteSeries([(0,1), (3, 4), (5, 6)], '(0; 8>')
# fs[0] - NotInDomainError's !
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:

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 a domain:

fs = FunctionSeries(lambda x: x**2, '<-2;2>')

ModuloSeries

ModuloSeries allow you to wrap a finite series in repetition.

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.

You can create Ranges as follows:

Range(-5, 5, True, False) == Range('<-5;5)')

First boolean argument signifies whether the interval is left-closed, and second whether it is right-closed.

Range's are immutable and hashable. They can be sliced:

Range('<-5;5>')[0:] == Range('<0;5>')

You can check whether a range contains a point

5 not in Range('<-1;5)')

Or you can check for strict inclusion

Range('<-1;1>') in Range('<-2;2>')