/**
   * Form a new external, quantized state model (QSS-specific).
   *
   * @param stateIdx The state index.
   */
  protected final void _triggerQuantizationEventWorker(final int stateIdx) {

    // Note the superclass takes care of updating status variables and so on.

    // Initialize.
    final ModelPolynomial qStateMdl = _qStateMdls[stateIdx];
    final ModelPolynomial cStateMdl = _cStateMdls[stateIdx];
    final double dtStateMdl = _currSimTime.subtractToDouble(cStateMdl.tMdl);

    // Update the external, quantized state model.
    qStateMdl.tMdl = _currSimTime;
    qStateMdl.coeffs[0] = cStateMdl.evaluate(dtStateMdl);
    qStateMdl.coeffs[1] = cStateMdl.evaluateDerivative(dtStateMdl);
  }
  /** Form new internal, continuous state models (QSS-specific). */
  protected final void _triggerRateEventWorker() throws Exception {

    // Note the superclass takes care of updating status variables and so on.

    // Get values, at {_currSimTime}, of arguments to derivative function.
    //   In general, expect the integrator formed all of its
    // continuous state models at the same time.  If so, can find a
    // single delta-time, rather than having to find multiple differences
    // from {_currSimTime}.  Know that finding time differences is
    // expensive in Ptolemy, so want to avoid doing that if possible.
    //   However, there is a chance that the continuous state models were
    // formed at different times.  For example:
    // (1) User can reset a single state at any simulation time.
    // (2) In future, might be possible to avoid updating a
    // continuous state model if know none of its arguments changed.
    Time tStateMdl = null;
    double dtStateMdl = 0;
    for (int ii = 0; ii < _stateCt; ++ii) {
      final ModelPolynomial cStateMdl = _cStateMdls[ii];
      // Check for different model time.  Note testing object identity OK.
      if (cStateMdl.tMdl != tStateMdl) {
        tStateMdl = cStateMdl.tMdl;
        dtStateMdl = _currSimTime.subtractToDouble(tStateMdl);
      }
      _stateVals_xx[ii] = cStateMdl.evaluate(dtStateMdl);
    }
    // In general, don't expect input variable models to have same times.
    for (int ii = 0; ii < _ivCt; ++ii) {
      _ivVals_xx[ii] = _ivMdls[ii].evaluate(_currSimTime);
    }

    // Evaluate derivative function at {_currSimTime}.
    int retVal =
        _derivFcn.evaluateDerivatives(_currSimTime, _stateVals_xx, _ivVals_xx, _stateDerivs_xx);
    if (0 != retVal) {
      throw new Exception("_derivFcn.evalDerivs() returned " + retVal);
    }

    // Update the internal, continuous state models.
    //   Note this is a partial update, since don't yet know the second
    // derivatives.  Do the update now so that, when find the sample point
    // needed to estimate second derivatives, will be able to use as much
    // current information about the continuous state as possible.
    //   This also updates the rate model, which is just the derivative of
    // the state model.
    for (int ii = 0; ii < _stateCt; ++ii) {
      final ModelPolynomial cStateMdl = _cStateMdls[ii];
      cStateMdl.tMdl = _currSimTime;
      cStateMdl.coeffs[0] = _stateVals_xx[ii];
      cStateMdl.coeffs[1] = _stateDerivs_xx[ii];
      cStateMdl.coeffs[2] = 0;
    }

    // Choose a sample time, different from {_currSimTime}.
    //   For estimating second derivatives.
    final double dtSampleFD = 1e-8 * Math.max(1, Math.abs(_currSimTime.getDoubleValue()));
    double dtSample = Double.POSITIVE_INFINITY;
    for (int ii = 0; ii < _stateCt; ++ii) {
      final double derivii = _stateDerivs_xx[ii];
      double dtii;
      if (derivii != 0) {
        dtii = _dqs[ii] / Math.abs(derivii);
      } else {
        dtii = dtSampleFD;
      }
      if (dtii < dtSample && dtii > 0.0) {
        dtSample = dtii;
      }
    }
    assert (dtSample > 0);
    final Time tSample = _currSimTime.addUnchecked(dtSample);

    // Get values, at {tSample}, of arguments to derivative function.
    //   Note that here, know all continous state models have same time.
    // Therefore can use same delta-time for all evals.
    for (int ii = 0; ii < _stateCt; ++ii) {
      _stateVals_xx[ii] = _cStateMdls[ii].evaluate(dtSample);
    }
    for (int ii = 0; ii < _ivCt; ++ii) {
      _ivVals_xx[ii] = _ivMdls[ii].evaluate(tSample);
    }

    // Evaluate derivative function at {tSample}.
    retVal =
        _derivFcn.evaluateDerivatives(tSample, _stateVals_xx, _ivVals_xx, _stateDerivsSample_xx);
    if (0 != retVal) {
      throw new Exception("_derivFcn.evalDerivs() returned " + retVal);
    }

    // Update the internal, continuous state models.
    final double oneOverTwoDtSample = 0.5 / dtSample;
    for (int ii = 0; ii < _stateCt; ++ii) {
      _cStateMdls[ii].coeffs[2] =
          oneOverTwoDtSample * (_stateDerivsSample_xx[ii] - _stateDerivs_xx[ii]);
    }
  }