diff --git a/roughpy/src/args/kwargs_to_path_metadata.cpp b/roughpy/src/args/kwargs_to_path_metadata.cpp index 43ccd465..85d2d095 100644 --- a/roughpy/src/args/kwargs_to_path_metadata.cpp +++ b/roughpy/src/args/kwargs_to_path_metadata.cpp @@ -207,10 +207,12 @@ python::PyStreamMetaData python::kwargs_to_metadata(pybind11::kwargs& kwargs) if (kwargs.contains("support")) { auto support = kwargs_pop(kwargs, "support"); - if (!py::isinstance(support)) { + if (py::isinstance(support)) { md.support = intervals::RealInterval( support.cast() ); + } else { + RPY_THROW(py::type_error, "Support must be an Interval"); } } diff --git a/roughpy/src/streams/tensor_valued_stream.cpp b/roughpy/src/streams/tensor_valued_stream.cpp index 1275233d..3e9224ac 100644 --- a/roughpy/src/streams/tensor_valued_stream.cpp +++ b/roughpy/src/streams/tensor_valued_stream.cpp @@ -388,15 +388,20 @@ static PyObject* stvs_from_values(PyObject* cls, increment_data.reserve(data.size() - 1); param_t min_difference = std::numeric_limits::infinity(); - auto previous = ctx->tensor_to_lie(initial_value.log()); + // auto previous = ctx->tensor_to_lie(initial_value.log()); + FreeTensor previous = initial_value; for (Py_ssize_t i = 1; i < size; ++i) { param_t param_diff = data[i].first - data[i - 1].first; if (param_diff < min_difference) { min_difference = param_diff; } - auto current = ctx->tensor_to_lie(data[i].second.log()); + auto increment = previous.antipode().mul(data[i].second); + increment_data.emplace_back(data[i].first, ctx->tensor_to_lie(increment.log())); + previous = data[i].second; - increment_data.emplace_back(data[i].first, current.sub(previous)); - previous = std::move(current); + // auto current = ctx->tensor_to_lie(data[i].second.log()); + + // increment_data.emplace_back(data[i].first, current.sub(previous)); + // previous = std::move(current); } /* @@ -418,7 +423,7 @@ static PyObject* stvs_from_values(PyObject* cls, if (!path_md.support) { path_md.support = intervals::RealInterval( data.front().first, - data.back().first + ldexp(1., *path_md.resolution)); + data.back().first + ldexp(1., -*path_md.resolution)); } /* diff --git a/streams/src/tensor_valued_stream.cpp b/streams/src/tensor_valued_stream.cpp index fa1433c1..9290d4f8 100644 --- a/streams/src/tensor_valued_stream.cpp +++ b/streams/src/tensor_valued_stream.cpp @@ -68,11 +68,13 @@ TensorValuedStream::StreamValue TensorValuedStream::value_at( RPY_THROW(std::invalid_argument, "param is not in the domain of this stream"); } + if (param == m_domain.inf()) { return m_initial_value; } + const intervals::RealInterval interval(m_domain.inf(), param); auto sig = p_increment_stream->signature(interval, *m_initial_value.context()); - return m_initial_value.context()->convert(sig.mul(m_initial_value), + return m_initial_value.context()->convert(m_initial_value.mul(sig), m_initial_value.storage_type()); } @@ -85,7 +87,7 @@ TensorValuedStream::StreamValue TensorValuedStream::terminal_value() const { auto sig = p_increment_stream->signature(m_domain, *m_initial_value.context()); - return m_initial_value.context()->convert(sig.mul(m_initial_value), + return m_initial_value.context()->convert(m_initial_value.mul(sig), m_initial_value.storage_type()); } diff --git a/tests/streams/test_tensor_valued_stream.py b/tests/streams/test_tensor_valued_stream.py index be5fa0ef..a62f8762 100644 --- a/tests/streams/test_tensor_valued_stream.py +++ b/tests/streams/test_tensor_valued_stream.py @@ -113,3 +113,27 @@ def test_tv_stream_from_values(): +def test_signature_value_stream(): + + ctx = rp.get_context(4, 3, rp.DPReal) + + base_stream = rp.BrownianStream.with_generator("pcg64", ctx=ctx, support=rp.RealInterval(0., 1.)) + ## sampled Brownian stream or level1 Brownian stream + + delta_t = 0.1 + + values = [ + (t, base_stream.signature(rp.RealInterval(0., t))) + for t in np.arange(0., 1., delta_t) + ] + + value_stream = rp.TensorValuedStream.from_values(values, ctx=ctx) + assert value_stream.initial_value() == values[0][1] + + epsilon = 0.03125 + for i in range(len(values)-1): + t = values[i][0] + sub_stream = value_stream.query(rp.RealInterval(t, t+delta_t+epsilon)) + + sig = sub_stream.terminal_value() + assert_array_almost_equal(sig, values[i+1][1])