示例#1
0
def sample_switching_models(
    models: Sequence,
    usage_seq: Sequence,
    X: Union[None, Sequence, Callable] = None,
    initial_conditions: Optional[Tuple[Sequence, Sequence]] = None,
    return_input: bool = False,
) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]:
    """ Sample from a non-stationary stochastic processes that switches between
    different ARMA models at given times.

    This functions sets the models' `history_` attribute appropriately to ensure
    consistency across time.

    Parameters
    ----------
    models
        Sequence of models to use.
    usage_seq
        Sequence identifying the model to use at each time steps. Models are
        labeled from `0` to `len(models) - 1`.
    X
        If given, this overrides the input source for the models. If it is a
        sequence, it should be at least as long as `len(usage_seq)`.
    initial_conditions
        A tuple, `(initial_y, initial_x)`, of recent samples of the output and
        input sequences used to seed the simulation. If these are not provided,
        they are assumed equal to zero.
    return_input
        If true, returns both output and input. If false (the default), returns only
        the output.

    Returns a sequence `Y` of generated samples. If `return_input` is true,
    returns a  tuple `(Y, X)` of generated output samples and input samples. If
    the `U` parameter was used and was a sequence, the output `X` simply mirrors
    the input.
    """
    # check the inputs
    if len(models) == 0:
        raise ValueError("No models given.")

    if np.min(usage_seq) < 0 or np.max(usage_seq) >= len(models):
        raise ValueError("Invalid entry in usage_seq vector.")

    # handle vector X
    if X is not None and not callable(X):
        if len(X) < len(usage_seq):
            raise ValueError("Not enough input values in X.")

        X_ret = X
        X = sources.Stream(X)
        have_X_ret = True
    else:
        X_ret = np.zeros(len(usage_seq))
        have_X_ret = False

    # handle default initial conditions
    if initial_conditions is None:
        initial_conditions = ([], [])

    # generate the samples
    Y_ret = np.zeros(len(usage_seq))
    usage_rle = rle_encode(usage_seq)
    ptr = 0
    for model_id, n_samples in usage_rle:
        model = models[model_id]

        # ensure proper history
        if ptr >= model.p:
            history_y = np.copy(Y_ret[ptr - model.p : ptr])
        else:
            n_left = model.p - ptr
            if len(initial_conditions[0]) >= n_left:
                history_y = np.hstack((initial_conditions[0][-n_left:], Y_ret[:ptr]))
            else:
                history_y = np.hstack(
                    (
                        np.zeros(n_left - len(initial_conditions[0])),
                        initial_conditions[0],
                        Y_ret[:ptr],
                    )
                )
        if ptr >= model.q:
            history_x = np.copy(X_ret[ptr - model.q : ptr])
        else:
            n_left = model.q - ptr
            if len(initial_conditions[1]) >= n_left:
                history_x = np.hstack((initial_conditions[1][-n_left:], X_ret[:ptr]))
            else:
                history_x = np.hstack(
                    (
                        np.zeros(n_left - len(initial_conditions[1])),
                        initial_conditions[1],
                        X_ret[:ptr],
                    )
                )

        model.history_ = (history_y, history_x)

        # generate and store the samples from this model
        crt_y, crt_x = model.transform(n_samples, X=X, return_input=True)

        Y_ret[ptr : ptr + n_samples] = crt_y

        if not have_X_ret:
            X_ret[ptr : ptr + n_samples] = crt_x

        ptr += n_samples

    if return_input:
        return Y_ret, X_ret
    else:
        return Y_ret
示例#2
0
 def test_reading_samples_from_empty_store_raises_index_error(self):
     src = sources.Stream([])
     with self.assertRaises(IndexError):
         src(size=1)
示例#3
0
 def setUp(self):
     rng = np.random.default_rng(2)
     self.n = 10
     self.data = rng.normal(size=self.n)
     self.src = sources.Stream(self.data)
示例#4
0
    def test_empty_result_if_zero_samples_requested_from_empty_store(self):
        src = sources.Stream([])
        y = src(size=0)

        self.assertEqual(len(y), 0)