@Override
  protected MatrixStore<Double> extractSolution() {

    final ExpressionsBasedModel tmpModel = this.getModel();

    if (tmpModel != null) {

      final List<Variable> tmpFreeVariables = tmpModel.getFreeVariables();
      final Set<Index> tmpFixedVariables = tmpModel.getFixedVariables();

      final PrimitiveDenseStore retVal =
          PrimitiveDenseStore.FACTORY.makeZero(
              tmpFixedVariables.size() + tmpFreeVariables.size(), 1);

      for (final Index tmpVariable : tmpFixedVariables) {
        retVal.set(
            tmpVariable.index, 0, tmpModel.getVariable(tmpVariable.index).getValue().doubleValue());
      }

      final MatrixStore<Double> tmpSolutionX = this.getSolutionX();
      for (int i = 0; i < tmpFreeVariables.size(); i++) {
        final Variable tmpVariable = tmpFreeVariables.get(i);
        final int tmpIndexOf = tmpModel.indexOf(tmpVariable);
        retVal.set(tmpIndexOf, 0, tmpSolutionX.doubleValue(i));
      }

      return retVal;

    } else {

      return this.getSolutionX().copy();
    }
  }
  @Override
  protected boolean validate() {

    boolean retVal = true;
    this.setState(State.VALID);

    try {

      final MatrixStore<Double> tmpQ = this.getQ();

      final Cholesky<Double> tmpCholesky = CholeskyDecomposition.makePrimitive();
      tmpCholesky.compute(tmpQ, true);

      if (!tmpCholesky.isSPD()) {
        // Not positive definite. Check if at least positive semidefinite.

        final Eigenvalue<Double> tmpEigenvalue = EigenvalueDecomposition.makePrimitive(true);
        tmpEigenvalue.compute(tmpQ, true);

        final MatrixStore<Double> tmpD = tmpEigenvalue.getD();

        for (int ij = 0; retVal && (ij < tmpD.getMinDim()); ij++) {
          if (tmpD.doubleValue(ij, ij) < ZERO) {
            retVal = false;
            this.setState(State.INVALID);
          }
        }
      }

      if (retVal) {
        // Q ok, check AE

        //                final MatrixStore<Double> tmpAE = this.getAE();
        //
        //                final LU<Double> tmpLU = LUDecomposition.makePrimitive();
        //                tmpLU.compute(tmpAE);
        //
        //                if (tmpLU.getRank() != tmpAE.getRowDim()) {
        //                    retVal = false;
        //                    this.setState(State.INVALID);
        //                }
      }

    } catch (final Exception ex) {

      retVal = false;
      this.setState(State.FAILED);
    }

    return retVal;
  }
  private QuadraticSolver buildIterationSolver(final boolean addSmallDiagonal) {

    MatrixStore<Double> tmpQ = this.getQ();
    final MatrixStore<Double> tmpC = this.getC();

    if (addSmallDiagonal) {

      final PhysicalStore<Double> tmpCopyQ = tmpQ.copy();

      final double tmpLargest = tmpCopyQ.aggregateAll(Aggregator.LARGEST);
      final double tmpRelativelySmall = MACHINE_DOUBLE_ERROR * tmpLargest;
      final double tmpPracticalLimit = MACHINE_DOUBLE_ERROR + IS_ZERO;
      final double tmpSmallToAdd = Math.max(tmpRelativelySmall, tmpPracticalLimit);

      final UnaryFunction<Double> tmpFunc = ADD.second(tmpSmallToAdd);

      tmpCopyQ.modifyDiagonal(0, 0, tmpFunc);
      tmpQ = tmpCopyQ;
    }

    if (this.hasEqualityConstraints()) {

      final MatrixStore<Double> tmpAE = this.getAE();
      final MatrixStore<Double> tmpBE = this.getBE();

      final int tmpZeroSize = tmpAE.getRowDim();

      final MatrixStore<Double> tmpUpperLeftAE = tmpQ;
      final MatrixStore<Double> tmpUpperRightAE = tmpAE.builder().transpose().build();
      final MatrixStore<Double> tmpLowerLefAE = tmpAE;
      final MatrixStore<Double> tmpLowerRightAE = ZeroStore.makePrimitive(tmpZeroSize, tmpZeroSize);

      final MatrixStore<Double> tmpSubAE =
          new AboveBelowStore<Double>(
              new LeftRightStore<Double>(tmpUpperLeftAE, tmpUpperRightAE),
              new LeftRightStore<Double>(tmpLowerLefAE, tmpLowerRightAE));

      final MatrixStore<Double> tmpUpperBE = tmpC;
      final MatrixStore<Double> tmpLowerBE = tmpBE;

      final MatrixStore<Double> tmpSubBE = new AboveBelowStore<Double>(tmpUpperBE, tmpLowerBE);

      return new Builder().equalities(tmpSubAE, tmpSubBE).build(options);

    } else {

      return new Builder().equalities(tmpQ, tmpC).build(options);
    }
  }
  private void extractSolution(final QuadraticSolver aSolver) {

    final MatrixStore<Double> tmpSolutionX = aSolver.getSolutionX();

    final int tmpCountVariables = this.countVariables();
    final int tmpCountEqualityConstraints = this.countEqualityConstraints();

    for (int i = 0; i < tmpCountVariables; i++) {
      this.setX(i, tmpSolutionX.doubleValue(i));
    }

    for (int i = 0; i < tmpCountEqualityConstraints; i++) {
      this.setLE(i, tmpSolutionX.doubleValue(tmpCountVariables + i));
    }
  }