Github user mengxr commented on a diff in the pull request:

    https://github.com/apache/spark/pull/12317#discussion_r59646323
  
    --- Diff: 
mllib-local/src/main/scala/org/apache/spark/ml/linalg/Matrices.scala ---
    @@ -0,0 +1,1026 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *    http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.spark.ml.linalg
    +
    +import java.util.{Arrays, Random}
    +
    +import scala.collection.mutable.{ArrayBuffer, ArrayBuilder => 
MArrayBuilder, HashSet => MHashSet}
    +
    +import breeze.linalg.{CSCMatrix => BSM, DenseMatrix => BDM, Matrix => BM}
    +import com.github.fommil.netlib.BLAS.{getInstance => blas}
    +
    +/**
    + * Trait for a local matrix.
    + */
    +sealed trait Matrix extends Serializable {
    +
    +  /** Number of rows. */
    +  def numRows: Int
    +
    +  /** Number of columns. */
    +  def numCols: Int
    +
    +  /** Flag that keeps track whether the matrix is transposed or not. False 
by default. */
    +  val isTransposed: Boolean = false
    +
    +  /** Converts to a dense array in column major. */
    +  def toArray: Array[Double] = {
    +    val newArray = new Array[Double](numRows * numCols)
    +    foreachActive { (i, j, v) =>
    +      newArray(j * numRows + i) = v
    +    }
    +    newArray
    +  }
    +
    +  /**
    +   * Returns an iterator of column vectors.
    +   * This operation could be expensive, depending on the underlying 
storage.
    +   */
    +  def colIter: Iterator[Vector]
    +
    +  /**
    +   * Returns an iterator of row vectors.
    +   * This operation could be expensive, depending on the underlying 
storage.
    +   */
    +  def rowIter: Iterator[Vector] = this.transpose.colIter
    +
    +  /** Converts to a breeze matrix. */
    +  private[ml] def toBreeze: BM[Double]
    +
    +  /** Gets the (i, j)-th element. */
    +  def apply(i: Int, j: Int): Double
    +
    +  /** Return the index for the (i, j)-th element in the backing array. */
    +  private[ml] def index(i: Int, j: Int): Int
    +
    +  /** Update element at (i, j) */
    +  private[ml] def update(i: Int, j: Int, v: Double): Unit
    +
    +  /** Get a deep copy of the matrix. */
    +  def copy: Matrix
    +
    +  /** Transpose the Matrix. Returns a new `Matrix` instance sharing the 
same underlying data. */
    +  def transpose: Matrix
    +
    +  /** Convenience method for `Matrix`-`DenseMatrix` multiplication. */
    +  def multiply(y: DenseMatrix): DenseMatrix = {
    +    val C: DenseMatrix = DenseMatrix.zeros(numRows, y.numCols)
    +    BLAS.gemm(1.0, this, y, 0.0, C)
    +    C
    +  }
    +
    +  /** Convenience method for `Matrix`-`DenseVector` multiplication. For 
binary compatibility. */
    +  def multiply(y: DenseVector): DenseVector = {
    +    multiply(y.asInstanceOf[Vector])
    +  }
    +
    +  /** Convenience method for `Matrix`-`Vector` multiplication. */
    +  def multiply(y: Vector): DenseVector = {
    +    val output = new DenseVector(new Array[Double](numRows))
    +    BLAS.gemv(1.0, this, y, 0.0, output)
    +    output
    +  }
    +
    +  /** A human readable representation of the matrix */
    +  override def toString: String = toBreeze.toString()
    +
    +  /** A human readable representation of the matrix with maximum lines and 
width */
    +  def toString(maxLines: Int, maxLineWidth: Int): String = 
toBreeze.toString(maxLines, maxLineWidth)
    +
    +  /**
    +   * Map the values of this matrix using a function. Generates a new 
matrix. Performs the
    +   * function on only the backing array. For example, an operation such as 
addition or
    +   * subtraction will only be performed on the non-zero values in a 
`SparseMatrix`.
    +   */
    +  private[spark] def map(f: Double => Double): Matrix
    +
    +  /**
    +   * Update all the values of this matrix using the function f. Performed 
in-place on the
    +   * backing array. For example, an operation such as addition or 
subtraction will only be
    +   * performed on the non-zero values in a `SparseMatrix`.
    +   */
    +  private[ml] def update(f: Double => Double): Matrix
    +
    +  /**
    +   * Applies a function `f` to all the active elements of dense and sparse 
matrix. The ordering
    +   * of the elements are not defined.
    +   *
    +   * @param f the function takes three parameters where the first two 
parameters are the row
    +   *          and column indices respectively with the type `Int`, and the 
final parameter is the
    +   *          corresponding value in the matrix with type `Double`.
    +   */
    +  private[spark] def foreachActive(f: (Int, Int, Double) => Unit)
    +
    +  /**
    +   * Find the number of non-zero active values.
    +   */
    +  def numNonzeros: Int
    +
    +  /**
    +   * Find the number of values stored explicitly. These values can be zero 
as well.
    +   */
    +  def numActives: Int
    +}
    +
    +/**
    + * Column-major dense matrix.
    + * The entry values are stored in a single array of doubles with columns 
listed in sequence.
    + * For example, the following matrix
    + * {{{
    + *   1.0 2.0
    + *   3.0 4.0
    + *   5.0 6.0
    + * }}}
    + * is stored as `[1.0, 3.0, 5.0, 2.0, 4.0, 6.0]`.
    + *
    + * @param numRows number of rows
    + * @param numCols number of columns
    + * @param values matrix entries in column major if not transposed or in 
row major otherwise
    + * @param isTransposed whether the matrix is transposed. If true, `values` 
stores the matrix in
    + *                     row major.
    + */
    +class DenseMatrix (
    +    val numRows: Int,
    +    val numCols: Int,
    +    val values: Array[Double],
    +    override val isTransposed: Boolean) extends Matrix {
    +
    +  require(values.length == numRows * numCols, "The number of values 
supplied doesn't match the " +
    +    s"size of the matrix! values.length: ${values.length}, numRows * 
numCols: ${numRows * numCols}")
    +
    +  /**
    +   * Column-major dense matrix.
    +   * The entry values are stored in a single array of doubles with columns 
listed in sequence.
    +   * For example, the following matrix
    +   * {{{
    +   *   1.0 2.0
    +   *   3.0 4.0
    +   *   5.0 6.0
    +   * }}}
    +   * is stored as `[1.0, 3.0, 5.0, 2.0, 4.0, 6.0]`.
    +   *
    +   * @param numRows number of rows
    +   * @param numCols number of columns
    +   * @param values matrix entries in column major
    +   */
    +  def this(numRows: Int, numCols: Int, values: Array[Double]) =
    +    this(numRows, numCols, values, false)
    +
    +  override def equals(o: Any): Boolean = o match {
    +    case m: Matrix => toBreeze == m.toBreeze
    +    case _ => false
    +  }
    +
    +  override def hashCode: Int = {
    +    com.google.common.base.Objects.hashCode(numRows: Integer, numCols: 
Integer, toArray)
    --- End diff --
    
    It could be replaced by `Seq(numRows, numCols, toArray).##`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to