def monteCarloError(self, xdata=None, monteCarlo=None):
        """
        Calculates :math:\sigma:math:-confidence regions on the model given some inputs.

        From the full covariance matrix (inverse of the Hessian) random
        samples are drawn, which are added to the parameters. With this new
        set of parameters the model is calculated. This procedure is done
        by default, 25 times.
        The standard deviation of the models is returned as the error bar.

        The calculation of the confidence region is delegated to the class
        MonteCarlo. For tweaking of that class can be done outside BaseFitter.

        Parameters
        ----------
        xdata : array_like
            input data over which to calculate the error bars.
        monteCarlo : MonteCarlo
            a ready-made MonteCarlo class.

        """
        if xdata is None: xdata = self.xdata
        if monteCarlo is None:
            monteCarlo = MonteCarlo(xdata,
                                    self.model,
                                    self.covariance,
                                    index=self.fitIndex)

        return monteCarlo.getError(xdata)
    def testMonteCarlo3(self, doplot=False):
        print("====== MonteCarlo 3 ===================")

        N = 101
        x = numpy.arange(N, dtype=float) * 0.1
        ran = numpy.random
        ran.seed(1235)
        noise = ran.standard_normal(N)

        ym = x * x + 0.03 * x + 0.05
        y1 = ym + 10 * noise

        pm = PolynomialModel(2)

        ftr = Fitter(x, pm)

        pars1 = ftr.fit(y1)
        stdv1 = ftr.getStandardDeviations()
        print("parameters : ", pars1)
        print("std devs   : ", stdv1)
        print("chisquared : ", ftr.chisq)

        lmce = ftr.monteCarloError()
        chisq = ftr.chisq

        mce = MonteCarlo(x, pm, ftr.covariance)
        mce1 = mce.getError()
        assertAAE(lmce, mce1)

        yfit = pm.result(x)
        s2 = numpy.sum(numpy.square((yfit - ym) / lmce))
        print(s2, math.sqrt(s2 / N))

        integral = numpy.sum(yfit)
        s1 = 0
        s2 = 0
        k = 0
        for k in range(1, 100001):
            rv = mce.randomVariant(x)
            s1 += numpy.sum(rv)
            s2 += numpy.sum(numpy.square(rv - yfit))
            if k % 10000 == 0:
                print("%6d  %10.3f %10.3f %10.3f" %
                      (k, integral, s1 / k, math.sqrt(s2 / k)))

        ### TBC  dont know why the factor 1000 is there. ########
        print(abs(integral - s1 / k), math.sqrt(s2 / (k * 1000)))
        self.assertTrue(abs(integral - s1 / k) < math.sqrt(s2 / (k * 1000)))

        if doplot:
            pyplot.plot(x, y1, 'b.')

            pyplot.plot(x, ym, 'k-')
            pyplot.plot(x, yfit, 'g-')
            pyplot.plot(x, yfit + lmce, 'r-')
            pyplot.plot(x, yfit - lmce, 'r-')
            pyplot.show()