def simulated_data_iter(
        self, n=None, pexact=None, add_priornoise=False, bootstrap=None
        ):
        """ Iterator that returns simulated data based upon a fit's data.

        Simulated data is generated from a fit's data ``fit.y`` by
        replacing the mean values in that data with random numbers
        drawn from a distribution whose mean is ``self.fcn(pexact)``
        and whose covariance matrix is the same as that of ``self.y``.
        Each iteration of the iterator returns new simulated data,
        with different random numbers for the means and a covariance
        matrix equal to that of ``self.y``. This iterator is used by
        ``self.simulated_fit_iter``.

        Typical usage::

            fit = nonlinear_fit(data=(x,y), prior=prior, fcn=fcn)
            ...
            for ysim, priorsim in fit.simulate_data_iter(n=10):
                fitsim = nonlinear_fit(data=(x, ysim), prior=priorsim, fcn=fcn)
                print(fitsim)
                print('chi2 =', gv.chi2(fit.p, fitsim.p))

        This code tests the fitting protocol on simulated data, comparing the
        best fit parameters in each case with the correct values (``fit.p``).
        The loop in this code is functionally the same as (but probably not
        as fast as)::

            for fitsim in fit.simulated_fit_iter(n=10):
                print(fitsim)
                print('chi2 =', gv.chi2(fit.p, fitsim.p))

        Args:
            n (int or None): Maximum number of iterations (equals
                infinity if ``None``).

            pexact (None or dict/array of numbers): Fit-parameter values for
                the underlying distribution used to generate simulated data;
                replaced by ``self.pmean`` if is ``None`` (default).

            add_priornoise (bool): Vary prior means if ``True``; otherwise
                vary only the means in ``self.y`` (default).

        Returns:
            An iterator that returns a 2-tuple containing simulated
            versions of self.y and self.prior: ``(ysim, priorsim)``.
        """
        pexact = self.pmean if pexact is None else pexact
        # bootstrap is old name for add_priornoise; keep for legacy code
        if bootstrap is not None:
            add_priornoise = bootstrap
        f = self.fcn(pexact) if self.x is False else self.fcn(self.x, pexact)
        y = copy.deepcopy(self.y)
        if isinstance(y, _gvar.BufferDict):
            # y,f dictionaries; fresh copy of y, reorder f
            tmp_f = _gvar.BufferDict([(k, f[k]) for k in y])
            y.buf += tmp_f.buf - _gvar.mean(y.buf)
        else:
            # y,f arrays; fresh copy of y
            y += numpy.asarray(f) - _gvar.mean(y)
        prior = copy.deepcopy(self.prior)
        if prior is None or not add_priornoise:
            yiter = _gvar.bootstrap_iter(y, n)
            for ysim in _gvar.bootstrap_iter(y, n):
                yield ysim, prior
        else:
            yp = numpy.empty(y.size + prior.size, object)
            yp[:y.size] = y.flat
            yp[y.size:] = prior.flat
            for ypsim in _gvar.bootstrap_iter(yp, n):
                y.flat = ypsim[:y.size]
                prior.flat = ypsim[y.size:]
                yield y, prior
Iterator that returns simulated data based upon a fit's data.

        Simulated data is generated from a fit's data ``fit.y`` by
        replacing the mean values in that data with random numbers
        drawn from a distribution whose mean is ``self.fcn(pexact)``
        and whose covariance matrix is the same as that of ``self.y``.
        Each iteration of the iterator returns new simulated data,
        with different random numbers for the means and a covariance
        matrix equal to that of ``self.y``. This iterator is used by
        ``self.simulated_fit_iter``.

        Typical usage::

            fit = nonlinear_fit(data=(x,y), prior=prior, fcn=fcn)
            ...
            for ysim, priorsim in fit.simulate_data_iter(n=10):
                fitsim = nonlinear_fit(data=(x, ysim), prior=priorsim, fcn=fcn)
                print(fitsim)
                print('chi2 =', gv.chi2(fit.p, fitsim.p))

        This code tests the fitting protocol on simulated data, comparing the
        best fit parameters in each case with the correct values (``fit.p``).
        The loop in this code is functionally the same as (but probably not
        as fast as)::

            for fitsim in fit.simulated_fit_iter(n=10):
                print(fitsim)
                print('chi2 =', gv.chi2(fit.p, fitsim.p))

        Args:
            n (int or None): Maximum number of iterations (equals
                infinity if ``None``).

            pexact (None or dict/array of numbers): Fit-parameter values for
                the underlying distribution used to generate simulated data;
                replaced by ``self.pmean`` if is ``None`` (default).

            add_priornoise (bool): Vary prior means if ``True``; otherwise
                vary only the means in ``self.y`` (default).

        Returns:
            An iterator that returns a 2-tuple containing simulated
            versions of self.y and self.prior: ``(ysim, priorsim)``.