/** {@inheritDoc} */
  public SparseDoubleVector getColumnVector(int column) {
    int i = 0;
    SparseDoubleVector columnValues = new CompactSparseVector(vectors.size());

    for (DoubleVector vector : vectors) columnValues.set(i++, vector.get(column));
    return columnValues;
  }
 public DoubleVector getRowVector(int row) {
   int cols = columns();
   DoubleVector vec = new DenseVector(cols);
   for (int c = 0; c < cols; ++c) {
     vec.set(c, get(row, c));
   }
   return vec;
 }
 /** Compute the dot product between two vectors. */
 private static double dotProduct(DoubleVector u, DoubleVector v) {
   double dot = 0;
   for (int i = 0; i < u.length(); ++i) {
     double a = u.get(i);
     double b = v.get(i);
     dot += u.get(i) * v.get(i);
   }
   return dot;
 }
 /** Generates a simple random vector. */
 private static DoubleVector generateInitialVector(int length, double mean, double std) {
   DoubleVector vector = new DenseVector(length);
   for (int i = 0; i < length; ++i) {
     double v = RANDOM.nextGaussian();
     v = std * v + mean;
     vector.set(i, v);
   }
   return vector;
 }
  /**
   * @param length CAUTION: This value is ignored
   * @return A random vector that is orthogonal to all previously created vectors
   */
  public DoubleVector generate() {
    if (generatedVectors.size() == vectorLength)
      throw new IllegalArgumentException("Too many vectors have been generated");

    DoubleVector vector = generateInitialVector(vectorLength, mean, std);
    for (DoubleVector otherVector : generatedVectors) {
      double uDotV = dotProduct(otherVector, vector);
      double uDotU = dotProduct(otherVector, otherVector);
      for (int i = 0; i < vectorLength; ++i) {
        double projection = otherVector.get(i) * uDotV / uDotU;
        vector.set(i, vector.get(i) - projection);
      }
    }
    generatedVectors.add(vector);
    return vector;
  }
  /** {@inheritDoc} */
  public synchronized int addColumn(Vector col) {
    if (isFinished)
      throw new IllegalStateException("Cannot add columns to a MatrixBuilder that is finished");

    DoubleVector column = Vectors.asDouble(col);

    if (column.length() > numRows) numRows = column.length();

    // Vector instances can take on the maximum possible array size when the
    // vector length isn't specified.  This ruins the matrix size
    // specification since the matrix shouldn't actually be that big.
    // However, because this is an implementation artifact, we can't check
    // for it explicitly with an exception.  Therefore, put in an assert to
    // indicate what is likely going on if asserts are enabled for debugging
    // they symptoms.
    assert column.length() != Integer.MAX_VALUE
        : "adding a column whose "
            + "length is Integer.MAX_VALUE (was likley left unspecified in the "
            + " constructor).";

    // Special case for sparse Vectors, for which we already know the
    // non-zero indices for the column
    if (column instanceof SparseVector) {
      SparseVector s = (SparseVector) column;
      int[] nonZero = s.getNonZeroIndices();
      nonZeroValues += nonZero.length;
      System.out.println(nonZero.length);
      try {
        matrixDos.writeInt(nonZero.length);
        for (int i : nonZero) {
          double val = column.get(i);
          matrixDos.writeInt(i); // write the row index
          matrixDos.writeFloat((float) val);
        }
      } catch (IOException ioe) {
        throw new IOError(ioe);
      }
    }
    // For dense Vectors, find which values are non-zero and write only
    // those
    else {
      int nonZero = 0;
      for (int i = 0; i < column.length(); ++i) {
        double d = column.get(i);
        if (d != 0d) nonZero++;
      }

      // Update the matrix count
      nonZeroValues += nonZero;
      try {
        matrixDos.writeInt(nonZero);
        // Write the number of non-zero values in the column
        for (int i = 0; i < column.length(); ++i) {
          double value = column.get(i);
          if (value != 0d) {
            matrixDos.writeInt(i); // write the row index
            matrixDos.writeFloat((float) value);
          }
        }
      } catch (IOException ioe) {
        throw new IOError(ioe);
      }
    }
    return ++curCol;
  }