@Override
 protected void init(Matrix c) {
   super.init(c);
   doubleA = DoubleCohoMatrix.create(dualA, true);
   doubleB = DoubleMatrix.create(dualB);
   doubleC = DoubleMatrix.create(dualC);
 }
 @Override
 protected LPBasis initialBasis(Matrix c) {
   LPBasis result = super.initialBasis(c);
   doubleA = DoubleCohoMatrix.create(dualA, true);
   doubleB = DoubleMatrix.create(dualB);
   doubleC = DoubleMatrix.create(dualC);
   return result;
 }
  // @Override
  // Find nextBasis using double and then check if it is correct by reduceCost and feasibility.
  // If failed, use super (double->interval->APR).
  // This is not a good strategy. Because once double failed, it's high probable that interval fails
  // too.
  // See APRDoubleHybridCohoSolver.
  protected LPBasis pivot(LPBasis currBasis) throws UnboundedLPError {
    try {
      BooleanMatrix basis = currBasis.booleanBasis(doubleA.ncols());
      CohoMatrix B = doubleA.trim(currBasis.basis());
      /*
       * find new column
       * A new efficient method to compute relativecost, see pp83-84 @ master thesis.
       */
      int newCol = 0;
      Matrix cb = doubleC.row(currBasis.basis());
      Matrix d = B.transpose().getSolution(cb).transpose();
      CohoNumber relativeCost = null;
      for (; newCol < ncols; newCol++) { // we don't want to introduce the added column
        if (basis.V(newCol).booleanValue())
          continue; // skip if it is in the basis, it's can't be the new basic column

        // compute d*Aj
        CohoNumber ctj = doubleA.col(newCol).dotProd(d); // use cohoMatrix dotProd
        // CohoMatrix Aj = doubleA.convert(doubleA.col(newCol),true);
        //				CohoMatrix Aj = (CohoMatrix)doubleA.col(newCol);
        //				ArrayList<Integer> pos = Aj.rowsAtCol()[0];
        //				CohoNumber ctj = d.V(pos.get(0)).mult(Aj.V(pos.get(0)));
        //				if(pos.size()>1)
        //					ctj = ctj.add(  d.V(pos.get(1)).mult(Aj.V(pos.get(1)))  );

        relativeCost = doubleC.V(newCol).sub(ctj);
        if (relativeCost.compareTo(0) < 0) {
          break;
        } // if relativeCost = 0; it is degeneracy, we have get the optimal one. we don't want to
          // continue it anymore
      }
      if (newCol == ncols) { // it may not be optimal
        return super.pivot(currBasis);
      }
      // return null;
      /*
       * find column to be evicted out
       */
      Matrix T0 = B.getSolution(doubleB);
      Matrix Tj = B.getSolution(doubleA.col(newCol));
      // argmin(t0i/tji)
      int evictBasis = -1;
      CohoNumber min = null;
      for (int i = 0; i < T0.length(); i++) {
        CohoNumber tji = Tj.V(i);
        if (tji.compareTo(0) <= 0) continue;
        CohoNumber r = T0.V(i).div(tji);
        if (min == null || min.compareTo(r) > 0) { // can't use >=0 anti-cycle algorihtm
          evictBasis = i;
          min = r;
        }
      }
      // This might be or not be unbounded LP
      if (evictBasis < 0) { // unbounded all tj is nonpositive for cj < 0
        return super.pivot(currBasis);
        // throw new UnboundedLPError("APRDoubleHybridCohoSolver.pivot(): The lp is unbouned using
        // double, try to use apr");
      }

      // reduceCost here will not throw SingularMatrixException, because if the basis is not
      // inveritable, the exception is throw before.
      // But it is possible the reduceCost is [-inf,inf]
      // if(reduceCost(currBasis,newCol,evictBasis).less(0)){
      if (costReduced(currBasis, newCol, evictBasis)) {
        int removeCol =
            currBasis
                .basis()
                .V(evictBasis)
                .intValue(); // get the column number of the i^th of current basis.
        // The basis could be infeasible or even not inveritable. Therfore, *Feasible function must
        // handle the SingularMatrixException.
        LPBasis newBasis =
            currBasis.replace(
                removeCol, newCol, LPBasis.BasisStatus.UNKNOWN, LPBasis.BasisStatus.UNKNOWN);
        if (cohoDualFeasible(newBasis)) { // sucess
          return newBasis;
        } else {
          return super.pivot(currBasis);
        }
      } else { // check fail
        return super.pivot(currBasis);
      }
    } catch (SingularMatrixException e) {
      // The basis found by double might be invertiable, therefore, it is possible to throw a
      // SingularMatrixException.
      return super.pivot(currBasis);
    }
  }