Skip to main content

A domain specific language for modeling and manipulating discrete time signals.

Project description

py-aiger logo
A domain specific language for modeling and manipulating discrete time signals.

Build Status codecov Updates

PyPI version License: MIT

About

This library aims to provide a domain specific language for modeling and manipulating discrete time signals. Intuitively, most of the time, the discrete time signal's value is undefined.

If discrete-signals isn't for you, I recommend checking out traces (which this library took design inspiration from). Both libraries offer a convenient way to model unevenly-spaced discrete time signals.

Installation

$ pip install discrete-signals

Usage

from discrete_signals import signal

x = signal([(0, 1), (1, 2), (2, 3)], start=0, end=10, tag='x')
y = signal([(0.5, 'a'), (1, 'b'), (2, 'c')], start=0, end=3, tag='y')

x
# start, end: [0, 10)
# data: [(0, {'x': 1}), (1, {'x': 2}), (2, {'x': 3})]

y
# start, end: [0, 3)
# data: [(0.5, {'y': 'a'}), (1, {'y': 'b'}), (2, {'y': 'c'})]

Parallel Composition

x | y
# start, end: [0, 10)
# data: [(0, {'x': 1}), (0.5, {'y': 'a'}), (1, {'x': 2, 'y': 'b'}), (2, {'x': 3, 'y': 'c'})]

Concatenation

x @ y
# start, end: [0, 13)
# data: [(0, {'x': 1}), (1, {'x': 2}), (2, {'x': 3}), (10.5, {'y': 'a'}), (11, {'y': 'b'}), (12, {'y': 'c'})]

Retagging/Relabeling

x.retag({'x': 'z'})
# start, end: [0, 10)
# data: [(0, {'z': 1}), (1, {'z': 2}), (2, {'z': 3})]

Time shifting

x >> 1.1
# start, end: [1.1, 11.1)
# data: [(1.1, {'x': 1}), (2.1, {'x': 2}), (3.1, {'x': 3})]

x << 1
# start, end: [-1, 9)
# data: [(-1, {'x': 1}), (0, {'x': 2}), (1, {'x': 3})]

Slicing

x[1:]
# start, end: [1, 10)
# data: [(1, {'x': 2}), (2, {'x': 3})]

x[:1]
# start, end: [0, 1)
# data: [(0, {'x': 1})]

Rolling Window

x.rolling(1, 3)
# start, end: [-1, 7)
# data: [(-1, {'x': (1, 2)}), (0, {'x': (2, 3)}), (1, {'x': (3,)})]

Mapping a Function

One perform a point wise transform of the signal. For example, the following is equivalent to retagging the signal and adding 1.

x.transform(lambda val: {'y': val['x'] + 1})
# start, end: [0, 10)
# data: [(0, {'y': 2}), (1, {'y': 3}), (2, {'y': 4})]

Alternatively, DiscreteSignals support mapping the dictionary of values to a single value (and optionally tag it):

x.map(lambda val: str(val['x']), tag='z')
# start, end: [0, 10)
# data: [(0, {'z': '1'}), (1, {'z': '2'}), (2, {'z': '3'})]

Filter a signal

x.filter(lambda val: val['x'] > 2)
# start, end: [0, 10)
# data: [(2, {'x': 3})]

Projecting onto a subset of the tags.

(x | y).project({'x'})
# start, end: [0, 10)
# data: [(0, {'x': 1}), (1, {'x': 2}), (2, {'x': 3})]

Attributes

(x | y).tags
# {'x', 'y'}

x.values()
# SortedDict_values([defaultdict(None, {'x': 1}), defaultdict(None, {'x': 2}), defaultdict(None, {'x': 3})])

list(x.times())
# [0, 1, 2]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

discrete_signals-0.8.3.tar.gz (5.6 kB view hashes)

Uploaded Source

Built Distribution

discrete_signals-0.8.3-py3-none-any.whl (5.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page