Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
mir.series
Index-series
The module contains Series data structure with special iteration and indexing methods.
It is aimed to construct index or time-series using Mir and Phobos algorithms.
Public imports mir.ndslice.slice.
Authors:
Ilya Yaroshenko
Examples:
See_also: unionSeries, troykaSeries, troykaGalop.
import mir.ndslice; import mir.series; import mir.array.allocation: array; import mir.algorithm.setops: multiwayUnion; import mir.date: Date; import core.lifetime: move; import std.exception: collectExceptionMsg; ////////////////////////////////////// // Constructs two time-series. ////////////////////////////////////// auto index0 = [ Date(2017, 01, 01), Date(2017, 03, 01), Date(2017, 04, 01)]; auto data0 = [1.0, 3, 4]; auto series0 = index0.series(data0); auto index1 = [ Date(2017, 01, 01), Date(2017, 02, 01), Date(2017, 05, 01)]; auto data1 = [10.0, 20, 50]; auto series1 = index1.series(data1); ////////////////////////////////////// // asSlice method ////////////////////////////////////// assert(series0 .asSlice // ref qualifier is optional .map!((ref key, ref value) => key.yearMonthDay.month == value) .all); ////////////////////////////////////// // get* methods ////////////////////////////////////// auto refDate = Date(2017, 03, 01); auto missingDate = Date(2016, 03, 01); // default value double defaultValue = 100; assert(series0.get(refDate, defaultValue) == 3); assert(series0.get(missingDate, defaultValue) == defaultValue); // Exceptions handlers assert(series0.get(refDate) == 3); assert(series0.get(refDate, new Exception("My exception msg")) == 3); assert(series0.getVerbose(refDate) == 3); assert(series0.getExtraVerbose(refDate, "My exception msg") == 3); assert(collectExceptionMsg!Exception( series0.get(missingDate) ) == "Series double[date]: Missing required key"); assert(collectExceptionMsg!Exception( series0.get(missingDate, new Exception("My exception msg")) ) == "My exception msg"); assert(collectExceptionMsg!Exception( series0.getVerbose(missingDate) ) == "Series double[date]: Missing 2016-03-01 key"); assert(collectExceptionMsg!Exception( series0.getExtraVerbose(missingDate, "My exception msg") ) == "My exception msg. Series double[date]: Missing 2016-03-01 key"); // assign with get* series0.get(refDate) = 100; assert(series0.get(refDate) == 100); series0.get(refDate) = 3; // tryGet double val; assert(series0.tryGet(refDate, val)); assert(val == 3); assert(!series0.tryGet(missingDate, val)); assert(val == 3); // val was not changed ////////////////////////////////////// // Merges multiple series into one. // Allocates using GC. M // Makes exactly two allocations per merge: // one for index/time and one for data. ////////////////////////////////////// auto m0 = unionSeries(series0, series1); auto m1 = unionSeries(series1, series0); // order is matter assert(m0.index == [ Date(2017, 01, 01), Date(2017, 02, 01), Date(2017, 03, 01), Date(2017, 04, 01), Date(2017, 05, 01)]); assert(m0.index == m1.index); assert(m0.data == [ 1, 20, 3, 4, 50]); assert(m1.data == [10, 20, 3, 4, 50]); ////////////////////////////////////// // Joins two time-series into a one with two columns. ////////////////////////////////////// auto u = [index0, index1].multiwayUnion; auto index = u.move.array; auto data = slice!double([index.length, 2], 0); // initialized to 0 value auto series = index.series(data); series[0 .. $, 0][] = series0; // fill first column series[0 .. $, 1][] = series1; // fill second column assert(data == [ [1, 10], [0, 20], [3, 0], [4, 0], [0, 50]]);
Examples:
import mir.series; double[int] map; map[1] = 4.0; map[2] = 5.0; map[4] = 6.0; map[5] = 10.0; map[10] = 11.0; const s = series(map); double value; int key; assert(s.tryGet(2, value) && value == 5.0); assert(!s.tryGet(8, value)); assert(s.tryGetNext(2, value) && value == 5.0); assert(s.tryGetPrev(2, value) && value == 5.0); assert(s.tryGetNext(8, value) && value == 11.0); assert(s.tryGetPrev(8, value) && value == 10.0); assert(!s.tryGetFirst(8, 9, value)); assert(s.tryGetFirst(2, 10, value) && value == 5.0); assert(s.tryGetLast(2, 10, value) && value == 11.0); assert(s.tryGetLast(2, 8, value) && value == 10.0); key = 2; assert(s.tryGetNextUpdateKey(key, value) && key == 2 && value == 5.0); key = 2; assert(s.tryGetPrevUpdateKey(key, value) && key == 2 && value == 5.0); key = 8; assert(s.tryGetNextUpdateKey(key, value) && key == 10 && value == 11.0); key = 8; assert(s.tryGetPrevUpdateKey(key, value) && key == 5 && value == 10.0); key = 2; assert(s.tryGetFirstUpdateLower(key, 10, value) && key == 2 && value == 5.0); key = 10; assert(s.tryGetLastUpdateKey(2, key, value) && key == 10 && value == 11.0); key = 8; assert(s.tryGetLastUpdateKey(2, key, value) && key == 5 && value == 10.0);
- struct
mir_observation
(Index, Data);
aliasObservation
= mir_observation(Index, Data); - Plain index/time observation data structure. Observation are used as return tuple for for indexing Series.
- Index
index
; - Date, date-time, time, or index.
- Data
data
; - Value or ndslice.
- auto
observation
(Index, Data)(Indexindex
, Datadata
); - Convenient function for Observation construction.
- template
SeriesMap
(K, V) - Convinient alias for 1D Contiguous Series.Examples:
import std.traits; import mir.series; static assert (is(SeriesMap!(string, double) == Series!(string*, double*))); /// LHS, RHS static assert (isAssignable!(SeriesMap!(string, double), SeriesMap!(string, double))); static assert (isAssignable!(SeriesMap!(string, double), typeof(null))); static assert (isAssignable!(SeriesMap!(const string, double), SeriesMap!(string, double))); static assert (isAssignable!(SeriesMap!(string, const double), SeriesMap!(string, double))); static assert (isAssignable!(SeriesMap!(const string, const double), SeriesMap!(string, double))); static assert (isAssignable!(SeriesMap!(immutable string, double), SeriesMap!(immutable string, double))); static assert (isAssignable!(SeriesMap!(immutable string, const double), SeriesMap!(immutable string, double))); static assert (isAssignable!(SeriesMap!(const string, const double), SeriesMap!(immutable string, double))); static assert (isAssignable!(SeriesMap!(string, immutable double), SeriesMap!(string, immutable double))); static assert (isAssignable!(SeriesMap!(const string, immutable double), SeriesMap!(string, immutable double))); static assert (isAssignable!(SeriesMap!(const string, const double), SeriesMap!(string, immutable double))); // etc
- struct
mir_series
(IndexIterator_, Iterator_, size_t N_ = 1, SliceKind kind_ = Contiguous);
aliasSeries
= mir_series(IndexIterator_, Iterator_, ulong N_ = 1, mir_slice_kind kind_ = Contiguous); - Plain index series data structure.*.index[i]/*.key[i]/*.time corresponds to *.data[i]/*.value. Index is assumed to be sorted. sort can be used to normalise a series.Examples:1-dimensional data
auto index = [1, 2, 3, 4]; auto data = [2.1, 3.4, 5.6, 7.8]; auto series = index.series(data); const cseries = series; assert(series.contains(2)); assert( ()@trusted{ return (2 in series) is &data[1]; }() ); assert(!series.contains(5)); assert( ()@trusted{ return (5 in series) is null; }() ); assert(series.lowerBound(2) == series[0 .. 1]); assert(series.upperBound(2) == series[2 .. $]); assert(cseries.lowerBound(2) == cseries[0 .. 1]); assert(cseries.upperBound(2) == cseries[2 .. $]); // slicing type deduction for const / immutable series static assert(is(typeof(series[]) == Series!(int*, double*))); static assert(is(typeof(cseries[]) == Series!(const(int)*, const(double)*))); static assert(is(typeof((cast(immutable) series)[]) == Series!(immutable(int)*, immutable(double)*))); /// slicing auto seriesSlice = series[1 .. $ - 1]; assert(seriesSlice.index == index[1 .. $ - 1]); assert(seriesSlice.data == data[1 .. $ - 1]); static assert(is(typeof(series) == typeof(seriesSlice))); /// indexing assert(series[1] == observation(2, 3.4)); /// range primitives assert(series.length == 4); assert(series.front == observation(1, 2.1)); series.popFront; assert(series.front == observation(2, 3.4)); series.popBackN(10); assert(series.empty);
Examples:2-dimensional dataimport mir.date: Date; import mir.ndslice.topology: canonical, iota; size_t row_length = 5; auto index = [ Date(2017, 01, 01), Date(2017, 02, 01), Date(2017, 03, 01), Date(2017, 04, 01)]; // 1, 2, 3, 4, 5 // 6, 7, 8, 9, 10 // 11, 12, 13, 14, 15 // 16, 17, 18, 19, 20 auto data = iota!int([index.length, row_length], 1); // canonical and universal ndslices are more flexible then contiguous auto series = index.series(data.canonical); /// slicing auto seriesSlice = series[1 .. $ - 1, 2 .. 4]; assert(seriesSlice.index == index[1 .. $ - 1]); assert(seriesSlice.data == data[1 .. $ - 1, 2 .. 4]); static if (kindOf!(typeof(series.data)) != Contiguous) static assert(is(typeof(series) == typeof(seriesSlice))); /// indexing assert(series[1, 4] == observation(Date(2017, 02, 01), 10)); assert(series[2] == observation(Date(2017, 03, 01), iota!int([row_length], 11))); /// range primitives assert(series.length == 4); assert(series.length!1 == 5); series.popFront!1; assert(series.length!1 == 4);
Examples:Construct from nullimport mir.series; alias Map = Series!(string*, double*); Map a = null; auto b = Map(null); assert(a.empty); assert(b.empty); auto fun(Map a = null) { }
- alias
IndexIterator
= IndexIterator_; - alias
Iterator
= Iterator_; - enum size_t
N
; - enum SliceKind
kind
; - @property @trusted auto
index
();
const @property @trusted autoindex
();
immutable @property @trusted autoindex
();
@property @trusted voidindex
()(Slice!IndexIteratorindex
); - Index series is assumed to be sorted.IndexIterator is an iterator on top of date, date-time, time, or numbers or user defined types with defined opCmp. For example, Date*, DateTime*, immutable(long)*, mir.ndslice.iterator.IotaIterator.Examples:ditto
import mir.ndslice.slice: sliced; auto s = ["a", "b"].series([5, 6]); assert(s.index == ["a", "b"]); s.index = ["c", "d"].sliced; assert(s.index == ["c", "d"]);
- Slice!(Iterator, N, kind)
data
; - Data is any ndslice with only one constraints,
data
and index lengths should be equal. - IndexIterator
_index
; - alias
Index
= typeof((typeof(this)).init.index.front); - Index / Key / Time type aliases
- alias
Data
= typeof((typeof(this)).init.data.front); - Data / Value type aliases
- this()(Slice!IndexIterator
index
, Slice!(Iterator, N, kind)data
); - this(typeof(null));
- Construct from null
- const bool
opEquals
(RIndexIterator, RIterator, size_t RN, SliceKind rkind)(Series!(RIndexIterator, RIterator, RN, rkind)rhs
); - typeof(this)
opBinary
(string op : "~")(typeof(this)rhs
);
const autoopBinary
(string op : "~")(const typeof(this)rhs
); - Examples:
import mir.date: Date; ////////////////////////////////////// // Constructs two time-series. ////////////////////////////////////// auto index0 = [1,3,4]; auto data0 = [1.0, 3, 4]; auto series0 = index0.series(data0); auto index1 = [1,2,5]; auto data1 = [10.0, 20, 50]; auto series1 = index1.series(data1); ////////////////////////////////////// // Merges multiple series into one. ////////////////////////////////////// // Order is matter. // The first slice has higher priority. auto m0 = series0 ~ series1; auto m1 = series1 ~ series0; assert(m0.index == m1.index); assert(m0.data == [ 1, 20, 3, 4, 50]); assert(m1.data == [10, 20, 3, 4, 50]);
- void
opIndexAssign
(IndexIterator_, Iterator_, size_t N_, SliceKind kind_)(Series!(IndexIterator_, Iterator_, N_, kind_)r
); - Special [] = index-assign operator for index-series. Assigns data from
r
with index intersection. If a index index inr
is not in the index index for this series, then no op-assign will take place. This and r series are assumed to be sorted.Parameters:Series!(IndexIterator_, Iterator_, N_, kind_) r
rvalue index-series Examples:auto index = [1, 2, 3, 4]; auto data = [10.0, 10, 10, 10]; auto series = index.series(data); auto rindex = [0, 2, 4, 5]; auto rdata = [1.0, 2, 3, 4]; auto rseries = rindex.series(rdata); // series[] = rseries; series[] = rseries; assert(series.data == [10, 2, 10, 3]);
- void
opIndexOpAssign
(string op, IndexIterator_, Iterator_, size_t N_, SliceKind kind_)(auto ref Series!(IndexIterator_, Iterator_, N_, kind_)rSeries
); - Special [] op= index-op-assign operator for index-series. Op-assigns data from r with index intersection. If a index index in r is not in the index index for this series, then no op-assign will take place. This and r series are assumed to be sorted.Parameters:
Series!(IndexIterator_, Iterator_, N_, kind_) rSeries
rvalue index-series Examples:auto index = [1, 2, 3, 4]; auto data = [10.0, 10, 10, 10]; auto series = index.series(data); auto rindex = [0, 2, 4, 5]; auto rdata = [1.0, 2, 3, 4]; auto rseries = rindex.series(rdata); series[] += rseries; assert(series.data == [10, 12, 10, 13]);
- auto
lowerBound
(Index)(auto ref scope const Indexkey
);
const autolowerBound
(Index)(auto ref scope const Indexkey
); - This function uses a search with policy sp to find the largest left subrange on which t <
key
is true for all t. The search schedule and its complexity are documented in std.range.SearchPolicy. - auto
upperBound
(Index)(auto ref scope const Indexkey
);
const autoupperBound
(Index)(auto ref scope const Indexkey
); - This function uses a search with policy sp to find the largest right subrange on which t >
key
is true for all t. The search schedule and its complexity are documented in std.range.SearchPolicy. - ref @trusted auto
get
(Index, Value)(auto ref scope const Indexkey
, return ref Value_default
)
if (!is(Value : const(Exception)));
const ref autoget
(Index, Value)(auto ref scope const Indexkey
, return ref Value_default
)
if (!is(Value : const(Exception)));
immutable ref autoget
(Index, Value)(auto ref scope const Indexkey
, return ref Value_default
)
if (!is(Value : const(Exception)));
const autoget
(Index, Value)(auto ref scope const Indexkey
, Value_default
)
if (!is(Value : const(Exception)));
immutable autoget
(Index, Value)(auto ref scope const Indexkey
, Value_default
)
if (!is(Value : const(Exception))); - Gets data for the index.Parameters:
Index key
index Value _default
default value is returned if the series does not contains the index. Returns:data that corresponds to the index or default value. - ref @trusted auto
get
(Index)(auto ref scope const Indexkey
);
ref @trusted autoget
(Index)(auto ref scope const Indexkey
, lazy const Exceptionexc
);
const ref autoget
(Index)(auto ref scope const Indexkey
);
const ref autoget
(Index)(auto ref scope const Indexkey
, lazy const Exceptionexc
);
immutable ref autoget
(Index)(auto ref scope const Indexkey
);
immutable ref autoget
(Index)(auto ref scope const Indexkey
, lazy const Exceptionexc
); - Gets data for the index.Parameters:
Index key
index Exception exc
(lazy, optional) exception to throw if the series does not contains the index. Returns:data that corresponds to the index.Throws:Exception if the series does not contains the index.See Also: - ref auto
getVerbose
(Index)(auto ref scope const Indexkey
, stringfile
= __FILE__, intline
= __LINE__);
const ref autogetVerbose
(Index)(auto ref scope const Indexkey
, stringfile
= __FILE__, intline
= __LINE__);
immutable ref autogetVerbose
(Index)(auto ref scope const Indexkey
, stringfile
= __FILE__, intline
= __LINE__); - Gets data for the index (verbose exception).Parameters:
Index key
index Returns:data that corresponds to the index.Throws:Detailed exception if the series does not contains the index.See Also: - ref auto
getExtraVerbose
(Index)(auto ref scope const Indexkey
, stringexceptionInto
, stringfile
= __FILE__, intline
= __LINE__);
const ref autogetExtraVerbose
(Index)(auto ref scope const Indexkey
, stringexceptionInto
, stringfile
= __FILE__, intline
= __LINE__);
immutable ref autogetExtraVerbose
(Index)(auto ref scope const Indexkey
, stringexceptionInto
, stringfile
= __FILE__, intline
= __LINE__); - Gets data for the index (extra verbose exception).Parameters:
Index key
index Returns:data that corresponds to the index.Throws:Detailed exception if the series does not contains the index.See Also: - const @trusted bool
contains
(Index)(auto ref scope const Indexkey
); - @trusted auto
opBinaryRight
(string op : "in", Index)(auto ref scope const Indexkey
);
const autoopBinaryRight
(string op : "in", Index)(auto ref scope const Indexkey
);
immutable autoopBinaryRight
(string op : "in", Index)(auto ref scope const Indexkey
); - @trusted bool
tryGet
(Index, Value)(Indexkey
, ref scope Valueval
);
const booltryGet
(Index, Value)(Indexkey
, ref scope Valueval
);
immutable booltryGet
(Index, Value)(Indexkey
, ref scope Valueval
); - Tries to get the first value, such that key_i ==
key
.Returns:true on success. - bool
tryGetNext
(Index, Value)(auto ref scope const Indexkey
, ref scope Valueval
);
const booltryGetNext
(Index, Value)(auto ref scope const Indexkey
, ref scope Valueval
);
immutable booltryGetNext
(Index, Value)(auto ref scope const Indexkey
, ref scope Valueval
); - Tries to get the first value, such that key_i >=
key
.Returns:true on success. - @trusted bool
tryGetNextUpdateKey
(Index, Value)(ref scope Indexkey
, ref scope Valueval
);
const booltryGetNextUpdateKey
(Index, Value)(ref scope Indexkey
, ref scope Valueval
);
immutable booltryGetNextUpdateKey
(Index, Value)(ref scope Indexkey
, ref scope Valueval
); - Tries to get the first value, such that key_i >=
key
. Updateskey
with key_i.Returns:true on success. - bool
tryGetPrev
(Index, Value)(auto ref scope const Indexkey
, ref scope Valueval
);
const booltryGetPrev
(Index, Value)(auto ref scope const Indexkey
, ref scope Valueval
);
immutable booltryGetPrev
(Index, Value)(auto ref scope const Indexkey
, ref scope Valueval
); - Tries to get the last value, such that key_i <=
key
.Returns:true on success. - @trusted bool
tryGetPrevUpdateKey
(Index, Value)(ref scope Indexkey
, ref scope Valueval
);
const booltryGetPrevUpdateKey
(Index, Value)(ref scope Indexkey
, ref scope Valueval
);
immutable booltryGetPrevUpdateKey
(Index, Value)(ref scope Indexkey
, ref scope Valueval
); - Tries to get the last value, such that key_i <=
key
. Updateskey
with key_i.Returns:true on success. - @trusted bool
tryGetFirst
(Index, Value)(auto ref scope const IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
);
const booltryGetFirst
(Index, Value)(IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
);
immutable booltryGetFirst
(Index, Value)(IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
); - Tries to get the first value, such that
lowerBound
<= key_i <=upperBound
.Returns:true on success. - @trusted bool
tryGetFirstUpdateLower
(Index, Value)(ref IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
);
const booltryGetFirstUpdateLower
(Index, Value)(ref IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
);
immutable booltryGetFirstUpdateLower
(Index, Value)(ref IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
); - Tries to get the first value, such that
lowerBound
<= key_i <=upperBound
. UpdateslowerBound
with key_i.Returns:true on success. - @trusted bool
tryGetLast
(Index, Value)(IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
);
const booltryGetLast
(Index, Value)(IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
);
immutable booltryGetLast
(Index, Value)(IndexlowerBound
, auto ref scope const IndexupperBound
, ref scope Valueval
); - Tries to get the last value, such that
lowerBound
<= key_i <=upperBound
.Returns:true on success. - @trusted bool
tryGetLastUpdateKey
(Index, Value)(IndexlowerBound
, ref IndexupperBound
, ref scope Valueval
);
const booltryGetLastUpdateKey
(Index, Value)(IndexlowerBound
, ref IndexupperBound
, ref scope Valueval
);
immutable booltryGetLastUpdateKey
(Index, Value)(IndexlowerBound
, ref IndexupperBound
, ref scope Valueval
); - Tries to get the last value, such that
lowerBound
<= key_i <=upperBound
. UpdatesupperBound
with key_i.Returns:true on success. - @property auto
asSlice
()();
const @property autoasSlice
()();
immutable @property autoasSlice
()(); - Returns:1D Slice with creared with zip ([0] - key, [1] - value).See Also:map uses multiargument lambdas to handle zipped slices.
- const @property bool
empty
(size_t dimension = 0)()
if (dimension < N);
const @property size_tlength
(size_t dimension = 0)()
if (dimension < N);
@property autofront
(size_t dimension = 0)()
if (dimension < N);
@property autoback
(size_t dimension = 0)()
if (dimension < N);
@trusted voidpopFront
(size_t dimension = 0)()
if (dimension < N);
voidpopBack
(size_t dimension = 0)()
if (dimension < N);
@trusted voidpopFrontExactly
(size_t dimension = 0)(size_tn
)
if (dimension < N);
voidpopBackExactly
(size_t dimension = 0)(size_tn
)
if (dimension < N);
voidpopFrontN
(size_t dimension = 0)(size_tn
)
if (dimension < N);
voidpopBackN
(size_t dimension = 0)(size_tn
)
if (dimension < N);
const Slice!(IotaIterator!size_t)opSlice
(size_t dimension = 0)(size_ti
, size_tj
)
if (dimension < N);
const size_topDollar
(size_t dimension = 0)();
autoopIndex
(Slices...)(Slicesslices
)
if (allSatisfy!(templateOr!(is_Slice, isIndex), Slices));
const autoopIndex
(Slices...)(Slicesslices
)
if (allSatisfy!(templateOr!(is_Slice, isIndex), Slices));
immutable autoopIndex
(Slices...)(Slicesslices
)
if (allSatisfy!(templateOr!(is_Slice, isIndex), Slices)); - ndslice-like primitives
- ref @trusted auto
opAssign
(typeof(this)rvalue
) return;
ref autoopAssign
(RIndexIterator, RIterator)(Series!(RIndexIterator, RIterator, N, kind)rvalue
) return
if (isAssignable!(IndexIterator, RIndexIterator) && isAssignable!(Iterator, RIterator));
ref autoopAssign
(RIndexIterator, RIterator)(auto ref const Series!(RIndexIterator, RIterator, N, kind)rvalue
) return
if (isAssignable!(IndexIterator, LightConstOf!RIndexIterator) && isAssignable!(Iterator, LightConstOf!RIterator));
ref autoopAssign
(RIndexIterator, RIterator)(auto ref immutable Series!(RIndexIterator, RIterator, N, kind)rvalue
) return
if (isAssignable!(IndexIterator, LightImmutableOf!RIndexIterator) && isAssignable!(Iterator, LightImmutableOf!RIterator));
ref autoopAssign
(typeof(null)) return;
@property autosave
()(); - @property @trusted Series!(LightScopeOf!IndexIterator, LightScopeOf!Iterator, N, kind)
lightScope
()();
const @property @trusted Series!(LightConstOf!(LightScopeOf!IndexIterator), LightConstOf!(LightScopeOf!Iterator), N, kind)lightScope
()();
immutable @property @trusted Series!(LightConstOf!(LightScopeOf!IndexIterator), LightConstOf!(LightScopeOf!Iterator), N, kind)lightScope
()(); - const @property @trusted Series!(LightConstOf!IndexIterator, LightConstOf!Iterator, N, kind)
lightConst
()(); - immutable @property @trusted Series!(LightImmutableOf!IndexIterator, LightImmutableOf!Iterator, N, kind)
lightImmutable
()(); - const @property auto
toConst
()(); - const void
toString
(Writer)(ref scope Writerw
); - Examples:
import mir.series: series, sort; auto s = ["b", "a"].series([9, 8]).sort; import mir.format : text; assert(s.text == `{ index: [a, b], data: [8, 9] }`);
- auto
series
(IndexIterator, Iterator, size_t N, SliceKind kind)(Slice!IndexIteratorindex
, Slice!(Iterator, N, kind)data
);
autoseries
(Index, Data)(Index[]index
, Data[]data
);
autoseries
(IndexIterator, Data)(Slice!IndexIteratorindex
, Data[]data
);
autoseries
(Index, Iterator, size_t N, SliceKind kind)(Index[]index
, Slice!(Iterator, N, kind)data
); - Convenient function for Series construction.See Also:
Attention This overloads do not sort the data. User should call directly if index was not sorted.
- Series!(K*, V*)
series
(RK, RV, K = RK, V = RV)(RV[RK]aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init)));
Series!(RK*, RV*)series
(K, V, RK = const(K), RV = const(V))(const V[K]aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init)));
Series!(RK*, RV*)series
(K, V, RK = immutable(K), RV = immutable(V))(immutable V[K]aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init)));
autoseries
(K, V)(V[K]*aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init))); - Constructs a GC-allocated series from an associative array. Performs exactly two allocations.Parameters:
RV[RK] aa
associative array or a pointer to associative array Returns:sorted GC-allocated series.See Also:Examples:auto s = [1: 1.5, 3: 3.3, 2: 20.9].series; assert(s.index == [1, 2, 3]); assert(s.data == [1.5, 20.9, 3.3]); assert(s.data[s.findIndex(2)] == 20.9);
- auto
rcseries
(RK, RV, K = RK, V = RV)(RV[RK]aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init)));
autorcseries
(K, V, RK = const(K), RV = const(V))(const V[K]aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init)));
autorcseries
(K, V, RK = immutable(K), RV = immutable(V))(immutable V[K]aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init)));
autorcseries
(K, V)(V[K]*aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init))); - Constructs a RC-allocated series from an associative array. Performs exactly two allocations.Parameters:
RV[RK] aa
associative array or a pointer to associative array Returns:sorted RC-allocated series.See Also:Examples:auto s = [1: 1.5, 3: 3.3, 2: 20.9].rcseries; assert(s.index == [1, 2, 3]); assert(s.data == [1.5, 20.9, 3.3]); assert(s.data[s.findIndex(2)] == 20.9);
- Series!(K*, V*)
makeSeries
(Allocator, K, V)(auto ref Allocatorallocator
, V[K]aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init)));
Series!(K*, V*)makeSeries
(Allocator, K, V)(auto ref Allocatorallocator
, V[K]*aa
)
if (is(typeof(K.init < K.init)) && is(typeof(Unqual!K.init < Unqual!K.init))); - Constructs a manually allocated series from an associative array. Performs exactly two allocations.Parameters:
V[K] aa
= associative array or a pointer to associative array Returns:sorted manually allocated series.Examples:import std.experimental.allocator; import std.experimental.allocator.building_blocks.region; InSituRegion!(1024) allocator; auto aa = [1: 1.5, 3: 3.3, 2: 2.9]; auto s = (double[int] aa) @nogc @trusted pure nothrow { return allocator.makeSeries(aa); }(aa); auto indexArray = s.index.field; auto dataArray = s.data.field; assert(s.index == [1, 2, 3]); assert(s.data == [1.5, 2.9, 3.3]); assert(s.data[s.findIndex(2)] == 2.9); allocator.dispose(indexArray); allocator.dispose(dataArray);
- auto
assocArray
(IndexIterator, Iterator, size_t N, SliceKind kind)(Series!(IndexIterator, Iterator, N, kind)series
); - Returns a newly allocated associative array from a range of key/value tuples.Parameters:
Series!(IndexIterator, Iterator, N, kind) series
index / time Series, may not be sorted Returns:A newly allocated associative array out of elements of the input series. Returns a null associative array reference when given an empty series.Duplicates Associative arrays have unique keys. If r contains duplicate keys, then the result will contain the value of the last pair for that key in r.
Examples:import mir.ndslice; //iota and etc import mir.series; auto s = ["c", "a", "b"].series(3.iota!int); assert(s.assocArray == [ "c": 0, "a": 1, "b": 2, ]);
- enum auto
isSeries
(U); - Returns:true if U is a Series;
- size_t
findIndex
(IndexIterator, Iterator, size_t N, SliceKind kind, Index)(Series!(IndexIterator, Iterator, N, kind)series
, auto ref scope const Indexkey
); - Finds an index such that
series
.index[index] ==key
.Parameters:Series!(IndexIterator, Iterator, N, kind) series
series Index key
index to find in the series Returns:size_t.max if the series does not contain the key and appropriate index otherwise.Examples:auto index = [1, 2, 3, 4].sliced; auto data = [2.1, 3.4, 5.6, 7.8].sliced; auto series = index.series(data); assert(series.data[series.findIndex(3)] == 5.6); assert(series.findIndex(0) == size_t.max);
- size_t
find
(IndexIterator, Iterator, size_t N, SliceKind kind, Index)(Series!(IndexIterator, Iterator, N, kind)series
, auto ref scope const Indexkey
); - Finds a backward index such that
series
.index[$ - backward_index] ==key
.Parameters:Series!(IndexIterator, Iterator, N, kind) series
series Index key
index key to find in the series Returns:0 if the series does not contain the key and appropriate backward index otherwise.Examples:auto index = [1, 2, 3, 4].sliced; auto data = [2.1, 3.4, 5.6, 7.8].sliced; auto series = index.series(data); if (auto bi = series.find(3)) { assert(series.data[$ - bi] == 5.6); } else { assert(0); } assert(series.find(0) == 0);
- template
troykaGalop
(alias lfun, alias cfun, alias rfun) - Iterates union using three functions to handle each intersection case separately.Parameters:
lfun binary function that accepts left side key (and left side value) cfun trinary function that accepts left side key, (left side value,) and right side value rfun binary function that accepts right side key (and right side value) - void
troykaGalop
(IndexIterL, IterL, size_t LN, SliceKind lkind, IndexIterR, IterR, size_t RN, SliceKind rkind)(Series!(IndexIterL, IterL, LN, lkind)lhs
, Series!(IndexIterR, IterR, RN, rkind)rhs
); - Parameters:
Series!(IndexIterL, IterL, LN, lkind) lhs
left hand series Series!(IndexIterR, IterR, RN, rkind) rhs
right hand series - void
troykaGalop
(LeftRange, RightRange)(LeftRangelhs
, RightRangerhs
)
if (isInputRange!LeftRange && isInputRange!RightRange && !isSeries!LeftRange && !isSeries!RightRange); - Parameters:
LeftRange lhs
left hand input range RightRange rhs
right hand input range
- template
troykaSeries
(alias lfun, alias cfun, alias rfun) - Constructs union using three functions to handle each intersection case separately.Parameters:
lfun binary function that accepts left side key and left side value cfun trinary function that accepts left side key, left side value, and right side value rfun binary function that accepts right side key and right side value Examples:import mir.ndslice; auto a = [1, 2, 3, 9].sliced.series(iota!int([4], 1)); auto b = [0, 2, 4, 9].sliced.series(iota!int([4], 1) * 10.0); alias unionAlgorithm = troykaSeries!( (key, left) => left, (key, left, right) => left + right, (key, right) => -right, ); auto c = unionAlgorithm(a, b); assert(c.index == [0, 1, 2, 3, 4, 9]); assert(c.data == [-10, 1, 22, 3, -30, 44]);
- auto
troykaSeries
(IndexIterL, IterL, size_t LN, SliceKind lkind, IndexIterR, IterR, size_t RN, SliceKind rkind)(Series!(IndexIterL, IterL, LN, lkind)lhs
, Series!(IndexIterR, IterR, RN, rkind)rhs
); - Parameters:
Series!(IndexIterL, IterL, LN, lkind) lhs
left hand series Series!(IndexIterR, IterR, RN, rkind) rhs
right hand series Returns:GC-allocated union series with length equal to troykaLength
- template
rcTroykaSeries
(alias lfun, alias cfun, alias rfun) - Constructs union using three functions to handle each intersection case separately.Parameters:
lfun binary function that accepts left side key and left side value cfun trinary function that accepts left side key, left side value, and right side value rfun binary function that accepts right side key and right side value Examples:import mir.ndslice; auto a = [1, 2, 3, 9].sliced.series(iota!int([4], 1)); auto b = [0, 2, 4, 9].sliced.series(iota!int([4], 1) * 10.0); alias unionAlgorithm = rcTroykaSeries!( (key, left) => left, (key, left, right) => left + right, (key, right) => -right, ); auto c = unionAlgorithm(a, b); assert(c.index == [0, 1, 2, 3, 4, 9]); assert(c.data == [-10, 1, 22, 3, -30, 44]);
- auto
rcTroykaSeries
(IndexIterL, IterL, size_t LN, SliceKind lkind, IndexIterR, IterR, size_t RN, SliceKind rkind)(auto ref Series!(IndexIterL, IterL, LN, lkind)lhs
, auto ref Series!(IndexIterR, IterR, RN, rkind)rhs
); - Parameters:
Series!(IndexIterL, IterL, LN, lkind) lhs
left hand series Series!(IndexIterR, IterR, RN, rkind) rhs
right hand series Returns:RC-allocated union series with length equal to troykaLength
- size_t
troykaLength
(IndexIterL, IterL, size_t LN, SliceKind lkind, IndexIterR, IterR, size_t RN, SliceKind rkind)(Series!(IndexIterL, IterL, LN, lkind)lhs
, Series!(IndexIterR, IterR, RN, rkind)rhs
);
size_ttroykaLength
(LeftRange, RightRange)(LeftRangelhs
, RightRangerhs
)
if (!isSeries!LeftRange && !isSeries!RightRange); - Length for Troyka union handlers.Parameters:
Series!(IndexIterL, IterL, LN, lkind) lhs
left hand side series/range Series!(IndexIterR, IterR, RN, rkind) rhs
right hand side series/range Returns:Total count of lambda function calls in troykaGalop union handler. - template
troykaSeriesImpl
(alias lfun, alias cfun, alias rfun) -
- void
troykaSeriesImpl
(I, E, IndexIterL, IterL, size_t LN, SliceKind lkind, IndexIterR, IterR, size_t RN, SliceKind rkind, UI, UE)(Series!(IndexIterL, IterL, LN, lkind)lhs
, Series!(IndexIterR, IterR, RN, rkind)rhs
, Series!(UI*, UE*)uninitSlice
);
- auto
unionSeries
(IndexIterator, Iterator, size_t N, SliceKind kind, size_t C)(Series!(IndexIterator, Iterator, N, kind)[C]seriesTuple
...)
if (C > 1); - Merges multiple (time) series into one. Makes exactly one memory allocation for two series union and two memory allocation for three and more series union.Parameters:
Series!(IndexIterator, Iterator, N, kind)[C] seriesTuple
variadic static array of composed of series, each series must be sorted. Returns:sorted GC-allocated series. See_also Series.opBinary makeUnionSeriesExamples:import mir.date: Date; ////////////////////////////////////// // Constructs two time-series. ////////////////////////////////////// auto index0 = [1,3,4]; auto data0 = [1.0, 3, 4]; auto series0 = index0.series(data0); auto index1 = [1,2,5]; auto data1 = [10.0, 20, 50]; auto series1 = index1.series(data1); ////////////////////////////////////// // Merges multiple series into one. ////////////////////////////////////// // Order is matter. // The first slice has higher priority. auto m0 = unionSeries(series0, series1); auto m1 = unionSeries(series1, series0); assert(m0.index == m1.index); assert(m0.data == [ 1, 20, 3, 4, 50]); assert(m1.data == [10, 20, 3, 4, 50]);
Examples:import mir.date: Date; ////////////////////////////////////// // Constructs three time-series. ////////////////////////////////////// auto index0 = [1,3,4]; auto data0 = [1.0, 3, 4]; auto series0 = index0.series(data0); auto index1 = [1,2,5]; auto data1 = [10.0, 20, 50]; auto series1 = index1.series(data1); auto index2 = [1, 6]; auto data2 = [100.0, 600]; auto series2 = index2.series(data2); ////////////////////////////////////// // Merges multiple series into one. ////////////////////////////////////// // Order is matter. // The first slice has higher priority. auto m0 = unionSeries(series0, series1, series2); auto m1 = unionSeries(series1, series0, series2); auto m2 = unionSeries(series2, series0, series1); assert(m0.index == m1.index); assert(m0.index == m2.index); assert(m0.data == [ 1, 20, 3, 4, 50, 600]); assert(m1.data == [ 10, 20, 3, 4, 50, 600]); assert(m2.data == [100, 20, 3, 4, 50, 600]);
- auto
makeUnionSeries
(IndexIterator, Iterator, size_t N, SliceKind kind, size_t C, Allocator)(auto ref Allocatorallocator
, Series!(IndexIterator, Iterator, N, kind)[C]seriesTuple
...)
if (C > 1); - Merges multiple (time) series into one.Parameters:
Allocator allocator
memory allocator Series!(IndexIterator, Iterator, N, kind)[C] seriesTuple
variadic static array of composed of series. Returns:sorted manually allocated series. See_also unionSeriesExamples:import std.experimental.allocator; import std.experimental.allocator.building_blocks.region; ////////////////////////////////////// // Constructs two time-series. ////////////////////////////////////// auto index0 = [1,3,4]; auto data0 = [1.0, 3, 4]; auto series0 = index0.series(data0); auto index1 = [1,2,5]; auto data1 = [10.0, 20, 50]; auto series1 = index1.series(data1); ////////////////////////////////////// // Merges multiple series into one. ////////////////////////////////////// InSituRegion!(1024) allocator; auto m0 = allocator.makeUnionSeries(series0, series1); auto m1 = allocator.makeUnionSeries(series1, series0); // order is matter assert(m0.index == m1.index); assert(m0.data == [ 1, 20, 3, 4, 50]); assert(m1.data == [10, 20, 3, 4, 50]); /// series should have the same sizes as after allocation allocator.dispose(m0.index.field); allocator.dispose(m0.data.field); allocator.dispose(m1.index.field); allocator.dispose(m1.data.field);
- auto
rcUnionSeries
(IndexIterator, Iterator, size_t N, SliceKind kind, size_t C)(Series!(IndexIterator, Iterator, N, kind)[C]seriesTuple
...)
if (C > 1); - Merges multiple (time) series into one.Parameters:
Series!(IndexIterator, Iterator, N, kind)[C] seriesTuple
variadic static array of composed of series. Returns:sorted manually allocated series. See_also unionSeriesExamples:import mir.rc.array; ////////////////////////////////////// // Constructs two time-series. ////////////////////////////////////// auto index0 = [1,3,4]; auto data0 = [1.0, 3, 4]; auto series0 = index0.series(data0); auto index1 = [1,2,5]; auto data1 = [10.0, 20, 50]; auto series1 = index1.series(data1); ////////////////////////////////////// // Merges multiple series into one. ////////////////////////////////////// Series!(RCI!int, RCI!double) m0 = rcUnionSeries(series0, series1); Series!(RCI!int, RCI!double) m1 = rcUnionSeries(series1, series0); // order is matter assert(m0.index == m1.index); assert(m0.data == [ 1, 20, 3, 4, 50]); assert(m1.data == [10, 20, 3, 4, 50]);
- auto
unionSeriesImpl
(I, E, IndexIterator, Iterator, size_t N, SliceKind kind, UI, UE)(Series!(IndexIterator, Iterator, N, kind)[]seriesTuple
, Series!(UI*, UE*, N)uninitSeries
); - Initialize preallocated series using union of multiple (time) series. Doesn't make any allocations.Parameters:
Series!(IndexIterator, Iterator, N, kind)[] seriesTuple
dynamic array composed of series. Series!(UI*, UE*, N) uninitSeries
uninitialized series with exactly required length. - @property ref V[K]
insertOrAssign
(V, K, IndexIterator, Iterator, size_t N, SliceKind kind)(return ref V[K]aa
, auto ref Series!(IndexIterator, Iterator, N, kind)series
); - Inserts or assigns a series to the associative array
aa
.Parameters:V[K] aa
associative array Series!(IndexIterator, Iterator, N, kind) series
series Returns:associative arrayExamples:auto a = [1: 3.0, 4: 2.0]; auto s = series([1, 2, 3], [10, 20, 30]); a.insertOrAssign = s; assert(a.series == series([1, 2, 3, 4], [10.0, 20, 30, 2]));
- @property ref V[K]
insert
(V, K, IndexIterator, Iterator, size_t N, SliceKind kind)(return ref V[K]aa
, auto ref Series!(IndexIterator, Iterator, N, kind)series
); - Inserts a series to the associative array
aa
.Parameters:V[K] aa
associative array Series!(IndexIterator, Iterator, N, kind) series
series Returns:associative arrayExamples:auto a = [1: 3.0, 4: 2.0]; auto s = series([1, 2, 3], [10, 20, 30]); a.insert = s; assert(a.series == series([1, 2, 3, 4], [3.0, 20, 30, 2]));
Copyright © 2016-2022 by Ilya Yaroshenko | Page generated by
Ddoc on Tue Jan 11 06:37:12 2022