Best Python code snippet using molecule_python
distributed.py
Source:distributed.py
1#2# Licensed to the Apache Software Foundation (ASF) under one or more3# contributor license agreements. See the NOTICE file distributed with4# this work for additional information regarding copyright ownership.5# The ASF licenses this file to You under the Apache License, Version 2.06# (the "License"); you may not use this file except in compliance with7# the License. You may obtain a copy of the License at8#9# http://www.apache.org/licenses/LICENSE-2.010#11# Unless required by applicable law or agreed to in writing, software12# distributed under the License is distributed on an "AS IS" BASIS,13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14# See the License for the specific language governing permissions and15# limitations under the License.16#17"""18Package for distributed linear algebra.19"""20import sys21if sys.version >= '3':22 long = int23from py4j.java_gateway import JavaObject24from pyspark import RDD, since25from pyspark.mllib.common import callMLlibFunc, JavaModelWrapper26from pyspark.mllib.linalg import _convert_to_vector, DenseMatrix, Matrix, QRDecomposition27from pyspark.mllib.stat import MultivariateStatisticalSummary28from pyspark.storagelevel import StorageLevel29__all__ = ['BlockMatrix', 'CoordinateMatrix', 'DistributedMatrix', 'IndexedRow',30 'IndexedRowMatrix', 'MatrixEntry', 'RowMatrix', 'SingularValueDecomposition']31class DistributedMatrix(object):32 """33 Represents a distributively stored matrix backed by one or34 more RDDs.35 """36 def numRows(self):37 """Get or compute the number of rows."""38 raise NotImplementedError39 def numCols(self):40 """Get or compute the number of cols."""41 raise NotImplementedError42class RowMatrix(DistributedMatrix):43 """44 Represents a row-oriented distributed Matrix with no meaningful45 row indices.46 :param rows: An RDD of vectors.47 :param numRows: Number of rows in the matrix. A non-positive48 value means unknown, at which point the number49 of rows will be determined by the number of50 records in the `rows` RDD.51 :param numCols: Number of columns in the matrix. A non-positive52 value means unknown, at which point the number53 of columns will be determined by the size of54 the first row.55 """56 def __init__(self, rows, numRows=0, numCols=0):57 """58 Note: This docstring is not shown publicly.59 Create a wrapper over a Java RowMatrix.60 Publicly, we require that `rows` be an RDD. However, for61 internal usage, `rows` can also be a Java RowMatrix62 object, in which case we can wrap it directly. This63 assists in clean matrix conversions.64 >>> rows = sc.parallelize([[1, 2, 3], [4, 5, 6]])65 >>> mat = RowMatrix(rows)66 >>> mat_diff = RowMatrix(rows)67 >>> (mat_diff._java_matrix_wrapper._java_model ==68 ... mat._java_matrix_wrapper._java_model)69 False70 >>> mat_same = RowMatrix(mat._java_matrix_wrapper._java_model)71 >>> (mat_same._java_matrix_wrapper._java_model ==72 ... mat._java_matrix_wrapper._java_model)73 True74 """75 if isinstance(rows, RDD):76 rows = rows.map(_convert_to_vector)77 java_matrix = callMLlibFunc("createRowMatrix", rows, long(numRows), int(numCols))78 elif (isinstance(rows, JavaObject)79 and rows.getClass().getSimpleName() == "RowMatrix"):80 java_matrix = rows81 else:82 raise TypeError("rows should be an RDD of vectors, got %s" % type(rows))83 self._java_matrix_wrapper = JavaModelWrapper(java_matrix)84 @property85 def rows(self):86 """87 Rows of the RowMatrix stored as an RDD of vectors.88 >>> mat = RowMatrix(sc.parallelize([[1, 2, 3], [4, 5, 6]]))89 >>> rows = mat.rows90 >>> rows.first()91 DenseVector([1.0, 2.0, 3.0])92 """93 return self._java_matrix_wrapper.call("rows")94 def numRows(self):95 """96 Get or compute the number of rows.97 >>> rows = sc.parallelize([[1, 2, 3], [4, 5, 6],98 ... [7, 8, 9], [10, 11, 12]])99 >>> mat = RowMatrix(rows)100 >>> print(mat.numRows())101 4102 >>> mat = RowMatrix(rows, 7, 6)103 >>> print(mat.numRows())104 7105 """106 return self._java_matrix_wrapper.call("numRows")107 def numCols(self):108 """109 Get or compute the number of cols.110 >>> rows = sc.parallelize([[1, 2, 3], [4, 5, 6],111 ... [7, 8, 9], [10, 11, 12]])112 >>> mat = RowMatrix(rows)113 >>> print(mat.numCols())114 3115 >>> mat = RowMatrix(rows, 7, 6)116 >>> print(mat.numCols())117 6118 """119 return self._java_matrix_wrapper.call("numCols")120 @since('2.0.0')121 def computeColumnSummaryStatistics(self):122 """123 Computes column-wise summary statistics.124 :return: :class:`MultivariateStatisticalSummary` object125 containing column-wise summary statistics.126 >>> rows = sc.parallelize([[1, 2, 3], [4, 5, 6]])127 >>> mat = RowMatrix(rows)128 >>> colStats = mat.computeColumnSummaryStatistics()129 >>> colStats.mean()130 array([ 2.5, 3.5, 4.5])131 """132 java_col_stats = self._java_matrix_wrapper.call("computeColumnSummaryStatistics")133 return MultivariateStatisticalSummary(java_col_stats)134 @since('2.0.0')135 def computeCovariance(self):136 """137 Computes the covariance matrix, treating each row as an138 observation.139 .. note:: This cannot be computed on matrices with more than 65535 columns.140 >>> rows = sc.parallelize([[1, 2], [2, 1]])141 >>> mat = RowMatrix(rows)142 >>> mat.computeCovariance()143 DenseMatrix(2, 2, [0.5, -0.5, -0.5, 0.5], 0)144 """145 return self._java_matrix_wrapper.call("computeCovariance")146 @since('2.0.0')147 def computeGramianMatrix(self):148 """149 Computes the Gramian matrix `A^T A`.150 .. note:: This cannot be computed on matrices with more than 65535 columns.151 >>> rows = sc.parallelize([[1, 2, 3], [4, 5, 6]])152 >>> mat = RowMatrix(rows)153 >>> mat.computeGramianMatrix()154 DenseMatrix(3, 3, [17.0, 22.0, 27.0, 22.0, 29.0, 36.0, 27.0, 36.0, 45.0], 0)155 """156 return self._java_matrix_wrapper.call("computeGramianMatrix")157 @since('2.0.0')158 def columnSimilarities(self, threshold=0.0):159 """160 Compute similarities between columns of this matrix.161 The threshold parameter is a trade-off knob between estimate162 quality and computational cost.163 The default threshold setting of 0 guarantees deterministically164 correct results, but uses the brute-force approach of computing165 normalized dot products.166 Setting the threshold to positive values uses a sampling167 approach and incurs strictly less computational cost than the168 brute-force approach. However the similarities computed will169 be estimates.170 The sampling guarantees relative-error correctness for those171 pairs of columns that have similarity greater than the given172 similarity threshold.173 To describe the guarantee, we set some notation:174 * Let A be the smallest in magnitude non-zero element of175 this matrix.176 * Let B be the largest in magnitude non-zero element of177 this matrix.178 * Let L be the maximum number of non-zeros per row.179 For example, for {0,1} matrices: A=B=1.180 Another example, for the Netflix matrix: A=1, B=5181 For those column pairs that are above the threshold, the182 computed similarity is correct to within 20% relative error183 with probability at least 1 - (0.981)^10/B^184 The shuffle size is bounded by the *smaller* of the following185 two expressions:186 * O(n log(n) L / (threshold * A))187 * O(m L^2^)188 The latter is the cost of the brute-force approach, so for189 non-zero thresholds, the cost is always cheaper than the190 brute-force approach.191 :param: threshold: Set to 0 for deterministic guaranteed192 correctness. Similarities above this193 threshold are estimated with the cost vs194 estimate quality trade-off described above.195 :return: An n x n sparse upper-triangular CoordinateMatrix of196 cosine similarities between columns of this matrix.197 >>> rows = sc.parallelize([[1, 2], [1, 5]])198 >>> mat = RowMatrix(rows)199 >>> sims = mat.columnSimilarities()200 >>> sims.entries.first().value201 0.91914503...202 """203 java_sims_mat = self._java_matrix_wrapper.call("columnSimilarities", float(threshold))204 return CoordinateMatrix(java_sims_mat)205 @since('2.0.0')206 def tallSkinnyQR(self, computeQ=False):207 """208 Compute the QR decomposition of this RowMatrix.209 The implementation is designed to optimize the QR decomposition210 (factorization) for the RowMatrix of a tall and skinny shape.211 Reference:212 Paul G. Constantine, David F. Gleich. "Tall and skinny QR213 factorizations in MapReduce architectures"214 ([[http://dx.doi.org/10.1145/1996092.1996103]])215 :param: computeQ: whether to computeQ216 :return: QRDecomposition(Q: RowMatrix, R: Matrix), where217 Q = None if computeQ = false.218 >>> rows = sc.parallelize([[3, -6], [4, -8], [0, 1]])219 >>> mat = RowMatrix(rows)220 >>> decomp = mat.tallSkinnyQR(True)221 >>> Q = decomp.Q222 >>> R = decomp.R223 >>> # Test with absolute values224 >>> absQRows = Q.rows.map(lambda row: abs(row.toArray()).tolist())225 >>> absQRows.collect()226 [[0.6..., 0.0], [0.8..., 0.0], [0.0, 1.0]]227 >>> # Test with absolute values228 >>> abs(R.toArray()).tolist()229 [[5.0, 10.0], [0.0, 1.0]]230 """231 decomp = JavaModelWrapper(self._java_matrix_wrapper.call("tallSkinnyQR", computeQ))232 if computeQ:233 java_Q = decomp.call("Q")234 Q = RowMatrix(java_Q)235 else:236 Q = None237 R = decomp.call("R")238 return QRDecomposition(Q, R)239 @since('2.2.0')240 def computeSVD(self, k, computeU=False, rCond=1e-9):241 """242 Computes the singular value decomposition of the RowMatrix.243 The given row matrix A of dimension (m X n) is decomposed into244 U * s * V'T where245 * U: (m X k) (left singular vectors) is a RowMatrix whose246 columns are the eigenvectors of (A X A')247 * s: DenseVector consisting of square root of the eigenvalues248 (singular values) in descending order.249 * v: (n X k) (right singular vectors) is a Matrix whose columns250 are the eigenvectors of (A' X A)251 For more specific details on implementation, please refer252 the Scala documentation.253 :param k: Number of leading singular values to keep (`0 < k <= n`).254 It might return less than k if there are numerically zero singular values255 or there are not enough Ritz values converged before the maximum number of256 Arnoldi update iterations is reached (in case that matrix A is ill-conditioned).257 :param computeU: Whether or not to compute U. If set to be258 True, then U is computed by A * V * s^-1259 :param rCond: Reciprocal condition number. All singular values260 smaller than rCond * s[0] are treated as zero261 where s[0] is the largest singular value.262 :returns: :py:class:`SingularValueDecomposition`263 >>> rows = sc.parallelize([[3, 1, 1], [-1, 3, 1]])264 >>> rm = RowMatrix(rows)265 >>> svd_model = rm.computeSVD(2, True)266 >>> svd_model.U.rows.collect()267 [DenseVector([-0.7071, 0.7071]), DenseVector([-0.7071, -0.7071])]268 >>> svd_model.s269 DenseVector([3.4641, 3.1623])270 >>> svd_model.V271 DenseMatrix(3, 2, [-0.4082, -0.8165, -0.4082, 0.8944, -0.4472, 0.0], 0)272 """273 j_model = self._java_matrix_wrapper.call(274 "computeSVD", int(k), bool(computeU), float(rCond))275 return SingularValueDecomposition(j_model)276 @since('2.2.0')277 def computePrincipalComponents(self, k):278 """279 Computes the k principal components of the given row matrix280 .. note:: This cannot be computed on matrices with more than 65535 columns.281 :param k: Number of principal components to keep.282 :returns: :py:class:`pyspark.mllib.linalg.DenseMatrix`283 >>> rows = sc.parallelize([[1, 2, 3], [2, 4, 5], [3, 6, 1]])284 >>> rm = RowMatrix(rows)285 >>> # Returns the two principal components of rm286 >>> pca = rm.computePrincipalComponents(2)287 >>> pca288 DenseMatrix(3, 2, [-0.349, -0.6981, 0.6252, -0.2796, -0.5592, -0.7805], 0)289 >>> # Transform into new dimensions with the greatest variance.290 >>> rm.multiply(pca).rows.collect() # doctest: +NORMALIZE_WHITESPACE291 [DenseVector([0.1305, -3.7394]), DenseVector([-0.3642, -6.6983]), \292 DenseVector([-4.6102, -4.9745])]293 """294 return self._java_matrix_wrapper.call("computePrincipalComponents", k)295 @since('2.2.0')296 def multiply(self, matrix):297 """298 Multiply this matrix by a local dense matrix on the right.299 :param matrix: a local dense matrix whose number of rows must match the number of columns300 of this matrix301 :returns: :py:class:`RowMatrix`302 >>> rm = RowMatrix(sc.parallelize([[0, 1], [2, 3]]))303 >>> rm.multiply(DenseMatrix(2, 2, [0, 2, 1, 3])).rows.collect()304 [DenseVector([2.0, 3.0]), DenseVector([6.0, 11.0])]305 """306 if not isinstance(matrix, DenseMatrix):307 raise ValueError("Only multiplication with DenseMatrix "308 "is supported.")309 j_model = self._java_matrix_wrapper.call("multiply", matrix)310 return RowMatrix(j_model)311class SingularValueDecomposition(JavaModelWrapper):312 """313 Represents singular value decomposition (SVD) factors.314 .. versionadded:: 2.2.0315 """316 @property317 @since('2.2.0')318 def U(self):319 """320 Returns a distributed matrix whose columns are the left321 singular vectors of the SingularValueDecomposition if computeU was set to be True.322 """323 u = self.call("U")324 if u is not None:325 mat_name = u.getClass().getSimpleName()326 if mat_name == "RowMatrix":327 return RowMatrix(u)328 elif mat_name == "IndexedRowMatrix":329 return IndexedRowMatrix(u)330 else:331 raise TypeError("Expected RowMatrix/IndexedRowMatrix got %s" % mat_name)332 @property333 @since('2.2.0')334 def s(self):335 """336 Returns a DenseVector with singular values in descending order.337 """338 return self.call("s")339 @property340 @since('2.2.0')341 def V(self):342 """343 Returns a DenseMatrix whose columns are the right singular344 vectors of the SingularValueDecomposition.345 """346 return self.call("V")347class IndexedRow(object):348 """349 Represents a row of an IndexedRowMatrix.350 Just a wrapper over a (long, vector) tuple.351 :param index: The index for the given row.352 :param vector: The row in the matrix at the given index.353 """354 def __init__(self, index, vector):355 self.index = long(index)356 self.vector = _convert_to_vector(vector)357 def __repr__(self):358 return "IndexedRow(%s, %s)" % (self.index, self.vector)359def _convert_to_indexed_row(row):360 if isinstance(row, IndexedRow):361 return row362 elif isinstance(row, tuple) and len(row) == 2:363 return IndexedRow(*row)364 else:365 raise TypeError("Cannot convert type %s into IndexedRow" % type(row))366class IndexedRowMatrix(DistributedMatrix):367 """368 Represents a row-oriented distributed Matrix with indexed rows.369 :param rows: An RDD of IndexedRows or (long, vector) tuples.370 :param numRows: Number of rows in the matrix. A non-positive371 value means unknown, at which point the number372 of rows will be determined by the max row373 index plus one.374 :param numCols: Number of columns in the matrix. A non-positive375 value means unknown, at which point the number376 of columns will be determined by the size of377 the first row.378 """379 def __init__(self, rows, numRows=0, numCols=0):380 """381 Note: This docstring is not shown publicly.382 Create a wrapper over a Java IndexedRowMatrix.383 Publicly, we require that `rows` be an RDD. However, for384 internal usage, `rows` can also be a Java IndexedRowMatrix385 object, in which case we can wrap it directly. This386 assists in clean matrix conversions.387 >>> rows = sc.parallelize([IndexedRow(0, [1, 2, 3]),388 ... IndexedRow(1, [4, 5, 6])])389 >>> mat = IndexedRowMatrix(rows)390 >>> mat_diff = IndexedRowMatrix(rows)391 >>> (mat_diff._java_matrix_wrapper._java_model ==392 ... mat._java_matrix_wrapper._java_model)393 False394 >>> mat_same = IndexedRowMatrix(mat._java_matrix_wrapper._java_model)395 >>> (mat_same._java_matrix_wrapper._java_model ==396 ... mat._java_matrix_wrapper._java_model)397 True398 """399 if isinstance(rows, RDD):400 rows = rows.map(_convert_to_indexed_row)401 # We use DataFrames for serialization of IndexedRows from402 # Python, so first convert the RDD to a DataFrame on this403 # side. This will convert each IndexedRow to a Row404 # containing the 'index' and 'vector' values, which can405 # both be easily serialized. We will convert back to406 # IndexedRows on the Scala side.407 java_matrix = callMLlibFunc("createIndexedRowMatrix", rows.toDF(),408 long(numRows), int(numCols))409 elif (isinstance(rows, JavaObject)410 and rows.getClass().getSimpleName() == "IndexedRowMatrix"):411 java_matrix = rows412 else:413 raise TypeError("rows should be an RDD of IndexedRows or (long, vector) tuples, "414 "got %s" % type(rows))415 self._java_matrix_wrapper = JavaModelWrapper(java_matrix)416 @property417 def rows(self):418 """419 Rows of the IndexedRowMatrix stored as an RDD of IndexedRows.420 >>> mat = IndexedRowMatrix(sc.parallelize([IndexedRow(0, [1, 2, 3]),421 ... IndexedRow(1, [4, 5, 6])]))422 >>> rows = mat.rows423 >>> rows.first()424 IndexedRow(0, [1.0,2.0,3.0])425 """426 # We use DataFrames for serialization of IndexedRows from427 # Java, so we first convert the RDD of rows to a DataFrame428 # on the Scala/Java side. Then we map each Row in the429 # DataFrame back to an IndexedRow on this side.430 rows_df = callMLlibFunc("getIndexedRows", self._java_matrix_wrapper._java_model)431 rows = rows_df.rdd.map(lambda row: IndexedRow(row[0], row[1]))432 return rows433 def numRows(self):434 """435 Get or compute the number of rows.436 >>> rows = sc.parallelize([IndexedRow(0, [1, 2, 3]),437 ... IndexedRow(1, [4, 5, 6]),438 ... IndexedRow(2, [7, 8, 9]),439 ... IndexedRow(3, [10, 11, 12])])440 >>> mat = IndexedRowMatrix(rows)441 >>> print(mat.numRows())442 4443 >>> mat = IndexedRowMatrix(rows, 7, 6)444 >>> print(mat.numRows())445 7446 """447 return self._java_matrix_wrapper.call("numRows")448 def numCols(self):449 """450 Get or compute the number of cols.451 >>> rows = sc.parallelize([IndexedRow(0, [1, 2, 3]),452 ... IndexedRow(1, [4, 5, 6]),453 ... IndexedRow(2, [7, 8, 9]),454 ... IndexedRow(3, [10, 11, 12])])455 >>> mat = IndexedRowMatrix(rows)456 >>> print(mat.numCols())457 3458 >>> mat = IndexedRowMatrix(rows, 7, 6)459 >>> print(mat.numCols())460 6461 """462 return self._java_matrix_wrapper.call("numCols")463 def columnSimilarities(self):464 """465 Compute all cosine similarities between columns.466 >>> rows = sc.parallelize([IndexedRow(0, [1, 2, 3]),467 ... IndexedRow(6, [4, 5, 6])])468 >>> mat = IndexedRowMatrix(rows)469 >>> cs = mat.columnSimilarities()470 >>> print(cs.numCols())471 3472 """473 java_coordinate_matrix = self._java_matrix_wrapper.call("columnSimilarities")474 return CoordinateMatrix(java_coordinate_matrix)475 @since('2.0.0')476 def computeGramianMatrix(self):477 """478 Computes the Gramian matrix `A^T A`.479 .. note:: This cannot be computed on matrices with more than 65535 columns.480 >>> rows = sc.parallelize([IndexedRow(0, [1, 2, 3]),481 ... IndexedRow(1, [4, 5, 6])])482 >>> mat = IndexedRowMatrix(rows)483 >>> mat.computeGramianMatrix()484 DenseMatrix(3, 3, [17.0, 22.0, 27.0, 22.0, 29.0, 36.0, 27.0, 36.0, 45.0], 0)485 """486 return self._java_matrix_wrapper.call("computeGramianMatrix")487 def toRowMatrix(self):488 """489 Convert this matrix to a RowMatrix.490 >>> rows = sc.parallelize([IndexedRow(0, [1, 2, 3]),491 ... IndexedRow(6, [4, 5, 6])])492 >>> mat = IndexedRowMatrix(rows).toRowMatrix()493 >>> mat.rows.collect()494 [DenseVector([1.0, 2.0, 3.0]), DenseVector([4.0, 5.0, 6.0])]495 """496 java_row_matrix = self._java_matrix_wrapper.call("toRowMatrix")497 return RowMatrix(java_row_matrix)498 def toCoordinateMatrix(self):499 """500 Convert this matrix to a CoordinateMatrix.501 >>> rows = sc.parallelize([IndexedRow(0, [1, 0]),502 ... IndexedRow(6, [0, 5])])503 >>> mat = IndexedRowMatrix(rows).toCoordinateMatrix()504 >>> mat.entries.take(3)505 [MatrixEntry(0, 0, 1.0), MatrixEntry(0, 1, 0.0), MatrixEntry(6, 0, 0.0)]506 """507 java_coordinate_matrix = self._java_matrix_wrapper.call("toCoordinateMatrix")508 return CoordinateMatrix(java_coordinate_matrix)509 def toBlockMatrix(self, rowsPerBlock=1024, colsPerBlock=1024):510 """511 Convert this matrix to a BlockMatrix.512 :param rowsPerBlock: Number of rows that make up each block.513 The blocks forming the final rows are not514 required to have the given number of rows.515 :param colsPerBlock: Number of columns that make up each block.516 The blocks forming the final columns are not517 required to have the given number of columns.518 >>> rows = sc.parallelize([IndexedRow(0, [1, 2, 3]),519 ... IndexedRow(6, [4, 5, 6])])520 >>> mat = IndexedRowMatrix(rows).toBlockMatrix()521 >>> # This IndexedRowMatrix will have 7 effective rows, due to522 >>> # the highest row index being 6, and the ensuing523 >>> # BlockMatrix will have 7 rows as well.524 >>> print(mat.numRows())525 7526 >>> print(mat.numCols())527 3528 """529 java_block_matrix = self._java_matrix_wrapper.call("toBlockMatrix",530 rowsPerBlock,531 colsPerBlock)532 return BlockMatrix(java_block_matrix, rowsPerBlock, colsPerBlock)533 @since('2.2.0')534 def computeSVD(self, k, computeU=False, rCond=1e-9):535 """536 Computes the singular value decomposition of the IndexedRowMatrix.537 The given row matrix A of dimension (m X n) is decomposed into538 U * s * V'T where539 * U: (m X k) (left singular vectors) is a IndexedRowMatrix540 whose columns are the eigenvectors of (A X A')541 * s: DenseVector consisting of square root of the eigenvalues542 (singular values) in descending order.543 * v: (n X k) (right singular vectors) is a Matrix whose columns544 are the eigenvectors of (A' X A)545 For more specific details on implementation, please refer546 the scala documentation.547 :param k: Number of leading singular values to keep (`0 < k <= n`).548 It might return less than k if there are numerically zero singular values549 or there are not enough Ritz values converged before the maximum number of550 Arnoldi update iterations is reached (in case that matrix A is ill-conditioned).551 :param computeU: Whether or not to compute U. If set to be552 True, then U is computed by A * V * s^-1553 :param rCond: Reciprocal condition number. All singular values554 smaller than rCond * s[0] are treated as zero555 where s[0] is the largest singular value.556 :returns: SingularValueDecomposition object557 >>> rows = [(0, (3, 1, 1)), (1, (-1, 3, 1))]558 >>> irm = IndexedRowMatrix(sc.parallelize(rows))559 >>> svd_model = irm.computeSVD(2, True)560 >>> svd_model.U.rows.collect() # doctest: +NORMALIZE_WHITESPACE561 [IndexedRow(0, [-0.707106781187,0.707106781187]),\562 IndexedRow(1, [-0.707106781187,-0.707106781187])]563 >>> svd_model.s564 DenseVector([3.4641, 3.1623])565 >>> svd_model.V566 DenseMatrix(3, 2, [-0.4082, -0.8165, -0.4082, 0.8944, -0.4472, 0.0], 0)567 """568 j_model = self._java_matrix_wrapper.call(569 "computeSVD", int(k), bool(computeU), float(rCond))570 return SingularValueDecomposition(j_model)571 @since('2.2.0')572 def multiply(self, matrix):573 """574 Multiply this matrix by a local dense matrix on the right.575 :param matrix: a local dense matrix whose number of rows must match the number of columns576 of this matrix577 :returns: :py:class:`IndexedRowMatrix`578 >>> mat = IndexedRowMatrix(sc.parallelize([(0, (0, 1)), (1, (2, 3))]))579 >>> mat.multiply(DenseMatrix(2, 2, [0, 2, 1, 3])).rows.collect()580 [IndexedRow(0, [2.0,3.0]), IndexedRow(1, [6.0,11.0])]581 """582 if not isinstance(matrix, DenseMatrix):583 raise ValueError("Only multiplication with DenseMatrix "584 "is supported.")585 return IndexedRowMatrix(self._java_matrix_wrapper.call("multiply", matrix))586class MatrixEntry(object):587 """588 Represents an entry of a CoordinateMatrix.589 Just a wrapper over a (long, long, float) tuple.590 :param i: The row index of the matrix.591 :param j: The column index of the matrix.592 :param value: The (i, j)th entry of the matrix, as a float.593 """594 def __init__(self, i, j, value):595 self.i = long(i)596 self.j = long(j)597 self.value = float(value)598 def __repr__(self):599 return "MatrixEntry(%s, %s, %s)" % (self.i, self.j, self.value)600def _convert_to_matrix_entry(entry):601 if isinstance(entry, MatrixEntry):602 return entry603 elif isinstance(entry, tuple) and len(entry) == 3:604 return MatrixEntry(*entry)605 else:606 raise TypeError("Cannot convert type %s into MatrixEntry" % type(entry))607class CoordinateMatrix(DistributedMatrix):608 """609 Represents a matrix in coordinate format.610 :param entries: An RDD of MatrixEntry inputs or611 (long, long, float) tuples.612 :param numRows: Number of rows in the matrix. A non-positive613 value means unknown, at which point the number614 of rows will be determined by the max row615 index plus one.616 :param numCols: Number of columns in the matrix. A non-positive617 value means unknown, at which point the number618 of columns will be determined by the max row619 index plus one.620 """621 def __init__(self, entries, numRows=0, numCols=0):622 """623 Note: This docstring is not shown publicly.624 Create a wrapper over a Java CoordinateMatrix.625 Publicly, we require that `rows` be an RDD. However, for626 internal usage, `rows` can also be a Java CoordinateMatrix627 object, in which case we can wrap it directly. This628 assists in clean matrix conversions.629 >>> entries = sc.parallelize([MatrixEntry(0, 0, 1.2),630 ... MatrixEntry(6, 4, 2.1)])631 >>> mat = CoordinateMatrix(entries)632 >>> mat_diff = CoordinateMatrix(entries)633 >>> (mat_diff._java_matrix_wrapper._java_model ==634 ... mat._java_matrix_wrapper._java_model)635 False636 >>> mat_same = CoordinateMatrix(mat._java_matrix_wrapper._java_model)637 >>> (mat_same._java_matrix_wrapper._java_model ==638 ... mat._java_matrix_wrapper._java_model)639 True640 """641 if isinstance(entries, RDD):642 entries = entries.map(_convert_to_matrix_entry)643 # We use DataFrames for serialization of MatrixEntry entries644 # from Python, so first convert the RDD to a DataFrame on645 # this side. This will convert each MatrixEntry to a Row646 # containing the 'i', 'j', and 'value' values, which can647 # each be easily serialized. We will convert back to648 # MatrixEntry inputs on the Scala side.649 java_matrix = callMLlibFunc("createCoordinateMatrix", entries.toDF(),650 long(numRows), long(numCols))651 elif (isinstance(entries, JavaObject)652 and entries.getClass().getSimpleName() == "CoordinateMatrix"):653 java_matrix = entries654 else:655 raise TypeError("entries should be an RDD of MatrixEntry entries or "656 "(long, long, float) tuples, got %s" % type(entries))657 self._java_matrix_wrapper = JavaModelWrapper(java_matrix)658 @property659 def entries(self):660 """661 Entries of the CoordinateMatrix stored as an RDD of662 MatrixEntries.663 >>> mat = CoordinateMatrix(sc.parallelize([MatrixEntry(0, 0, 1.2),664 ... MatrixEntry(6, 4, 2.1)]))665 >>> entries = mat.entries666 >>> entries.first()667 MatrixEntry(0, 0, 1.2)668 """669 # We use DataFrames for serialization of MatrixEntry entries670 # from Java, so we first convert the RDD of entries to a671 # DataFrame on the Scala/Java side. Then we map each Row in672 # the DataFrame back to a MatrixEntry on this side.673 entries_df = callMLlibFunc("getMatrixEntries", self._java_matrix_wrapper._java_model)674 entries = entries_df.rdd.map(lambda row: MatrixEntry(row[0], row[1], row[2]))675 return entries676 def numRows(self):677 """678 Get or compute the number of rows.679 >>> entries = sc.parallelize([MatrixEntry(0, 0, 1.2),680 ... MatrixEntry(1, 0, 2),681 ... MatrixEntry(2, 1, 3.7)])682 >>> mat = CoordinateMatrix(entries)683 >>> print(mat.numRows())684 3685 >>> mat = CoordinateMatrix(entries, 7, 6)686 >>> print(mat.numRows())687 7688 """689 return self._java_matrix_wrapper.call("numRows")690 def numCols(self):691 """692 Get or compute the number of cols.693 >>> entries = sc.parallelize([MatrixEntry(0, 0, 1.2),694 ... MatrixEntry(1, 0, 2),695 ... MatrixEntry(2, 1, 3.7)])696 >>> mat = CoordinateMatrix(entries)697 >>> print(mat.numCols())698 2699 >>> mat = CoordinateMatrix(entries, 7, 6)700 >>> print(mat.numCols())701 6702 """703 return self._java_matrix_wrapper.call("numCols")704 @since('2.0.0')705 def transpose(self):706 """707 Transpose this CoordinateMatrix.708 >>> entries = sc.parallelize([MatrixEntry(0, 0, 1.2),709 ... MatrixEntry(1, 0, 2),710 ... MatrixEntry(2, 1, 3.7)])711 >>> mat = CoordinateMatrix(entries)712 >>> mat_transposed = mat.transpose()713 >>> print(mat_transposed.numRows())714 2715 >>> print(mat_transposed.numCols())716 3717 """718 java_transposed_matrix = self._java_matrix_wrapper.call("transpose")719 return CoordinateMatrix(java_transposed_matrix)720 def toRowMatrix(self):721 """722 Convert this matrix to a RowMatrix.723 >>> entries = sc.parallelize([MatrixEntry(0, 0, 1.2),724 ... MatrixEntry(6, 4, 2.1)])725 >>> mat = CoordinateMatrix(entries).toRowMatrix()726 >>> # This CoordinateMatrix will have 7 effective rows, due to727 >>> # the highest row index being 6, but the ensuing RowMatrix728 >>> # will only have 2 rows since there are only entries on 2729 >>> # unique rows.730 >>> print(mat.numRows())731 2732 >>> # This CoordinateMatrix will have 5 columns, due to the733 >>> # highest column index being 4, and the ensuing RowMatrix734 >>> # will have 5 columns as well.735 >>> print(mat.numCols())736 5737 """738 java_row_matrix = self._java_matrix_wrapper.call("toRowMatrix")739 return RowMatrix(java_row_matrix)740 def toIndexedRowMatrix(self):741 """742 Convert this matrix to an IndexedRowMatrix.743 >>> entries = sc.parallelize([MatrixEntry(0, 0, 1.2),744 ... MatrixEntry(6, 4, 2.1)])745 >>> mat = CoordinateMatrix(entries).toIndexedRowMatrix()746 >>> # This CoordinateMatrix will have 7 effective rows, due to747 >>> # the highest row index being 6, and the ensuing748 >>> # IndexedRowMatrix will have 7 rows as well.749 >>> print(mat.numRows())750 7751 >>> # This CoordinateMatrix will have 5 columns, due to the752 >>> # highest column index being 4, and the ensuing753 >>> # IndexedRowMatrix will have 5 columns as well.754 >>> print(mat.numCols())755 5756 """757 java_indexed_row_matrix = self._java_matrix_wrapper.call("toIndexedRowMatrix")758 return IndexedRowMatrix(java_indexed_row_matrix)759 def toBlockMatrix(self, rowsPerBlock=1024, colsPerBlock=1024):760 """761 Convert this matrix to a BlockMatrix.762 :param rowsPerBlock: Number of rows that make up each block.763 The blocks forming the final rows are not764 required to have the given number of rows.765 :param colsPerBlock: Number of columns that make up each block.766 The blocks forming the final columns are not767 required to have the given number of columns.768 >>> entries = sc.parallelize([MatrixEntry(0, 0, 1.2),769 ... MatrixEntry(6, 4, 2.1)])770 >>> mat = CoordinateMatrix(entries).toBlockMatrix()771 >>> # This CoordinateMatrix will have 7 effective rows, due to772 >>> # the highest row index being 6, and the ensuing773 >>> # BlockMatrix will have 7 rows as well.774 >>> print(mat.numRows())775 7776 >>> # This CoordinateMatrix will have 5 columns, due to the777 >>> # highest column index being 4, and the ensuing778 >>> # BlockMatrix will have 5 columns as well.779 >>> print(mat.numCols())780 5781 """782 java_block_matrix = self._java_matrix_wrapper.call("toBlockMatrix",783 rowsPerBlock,784 colsPerBlock)785 return BlockMatrix(java_block_matrix, rowsPerBlock, colsPerBlock)786def _convert_to_matrix_block_tuple(block):787 if (isinstance(block, tuple) and len(block) == 2788 and isinstance(block[0], tuple) and len(block[0]) == 2789 and isinstance(block[1], Matrix)):790 blockRowIndex = int(block[0][0])791 blockColIndex = int(block[0][1])792 subMatrix = block[1]793 return ((blockRowIndex, blockColIndex), subMatrix)794 else:795 raise TypeError("Cannot convert type %s into a sub-matrix block tuple" % type(block))796class BlockMatrix(DistributedMatrix):797 """798 Represents a distributed matrix in blocks of local matrices.799 :param blocks: An RDD of sub-matrix blocks800 ((blockRowIndex, blockColIndex), sub-matrix) that801 form this distributed matrix. If multiple blocks802 with the same index exist, the results for803 operations like add and multiply will be804 unpredictable.805 :param rowsPerBlock: Number of rows that make up each block.806 The blocks forming the final rows are not807 required to have the given number of rows.808 :param colsPerBlock: Number of columns that make up each block.809 The blocks forming the final columns are not810 required to have the given number of columns.811 :param numRows: Number of rows of this matrix. If the supplied812 value is less than or equal to zero, the number813 of rows will be calculated when `numRows` is814 invoked.815 :param numCols: Number of columns of this matrix. If the supplied816 value is less than or equal to zero, the number817 of columns will be calculated when `numCols` is818 invoked.819 """820 def __init__(self, blocks, rowsPerBlock, colsPerBlock, numRows=0, numCols=0):821 """822 Note: This docstring is not shown publicly.823 Create a wrapper over a Java BlockMatrix.824 Publicly, we require that `blocks` be an RDD. However, for825 internal usage, `blocks` can also be a Java BlockMatrix826 object, in which case we can wrap it directly. This827 assists in clean matrix conversions.828 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),829 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])830 >>> mat = BlockMatrix(blocks, 3, 2)831 >>> mat_diff = BlockMatrix(blocks, 3, 2)832 >>> (mat_diff._java_matrix_wrapper._java_model ==833 ... mat._java_matrix_wrapper._java_model)834 False835 >>> mat_same = BlockMatrix(mat._java_matrix_wrapper._java_model, 3, 2)836 >>> (mat_same._java_matrix_wrapper._java_model ==837 ... mat._java_matrix_wrapper._java_model)838 True839 """840 if isinstance(blocks, RDD):841 blocks = blocks.map(_convert_to_matrix_block_tuple)842 # We use DataFrames for serialization of sub-matrix blocks843 # from Python, so first convert the RDD to a DataFrame on844 # this side. This will convert each sub-matrix block845 # tuple to a Row containing the 'blockRowIndex',846 # 'blockColIndex', and 'subMatrix' values, which can847 # each be easily serialized. We will convert back to848 # ((blockRowIndex, blockColIndex), sub-matrix) tuples on849 # the Scala side.850 java_matrix = callMLlibFunc("createBlockMatrix", blocks.toDF(),851 int(rowsPerBlock), int(colsPerBlock),852 long(numRows), long(numCols))853 elif (isinstance(blocks, JavaObject)854 and blocks.getClass().getSimpleName() == "BlockMatrix"):855 java_matrix = blocks856 else:857 raise TypeError("blocks should be an RDD of sub-matrix blocks as "858 "((int, int), matrix) tuples, got %s" % type(blocks))859 self._java_matrix_wrapper = JavaModelWrapper(java_matrix)860 @property861 def blocks(self):862 """863 The RDD of sub-matrix blocks864 ((blockRowIndex, blockColIndex), sub-matrix) that form this865 distributed matrix.866 >>> mat = BlockMatrix(867 ... sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),868 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))]), 3, 2)869 >>> blocks = mat.blocks870 >>> blocks.first()871 ((0, 0), DenseMatrix(3, 2, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0], 0))872 """873 # We use DataFrames for serialization of sub-matrix blocks874 # from Java, so we first convert the RDD of blocks to a875 # DataFrame on the Scala/Java side. Then we map each Row in876 # the DataFrame back to a sub-matrix block on this side.877 blocks_df = callMLlibFunc("getMatrixBlocks", self._java_matrix_wrapper._java_model)878 blocks = blocks_df.rdd.map(lambda row: ((row[0][0], row[0][1]), row[1]))879 return blocks880 @property881 def rowsPerBlock(self):882 """883 Number of rows that make up each block.884 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),885 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])886 >>> mat = BlockMatrix(blocks, 3, 2)887 >>> mat.rowsPerBlock888 3889 """890 return self._java_matrix_wrapper.call("rowsPerBlock")891 @property892 def colsPerBlock(self):893 """894 Number of columns that make up each block.895 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),896 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])897 >>> mat = BlockMatrix(blocks, 3, 2)898 >>> mat.colsPerBlock899 2900 """901 return self._java_matrix_wrapper.call("colsPerBlock")902 @property903 def numRowBlocks(self):904 """905 Number of rows of blocks in the BlockMatrix.906 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),907 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])908 >>> mat = BlockMatrix(blocks, 3, 2)909 >>> mat.numRowBlocks910 2911 """912 return self._java_matrix_wrapper.call("numRowBlocks")913 @property914 def numColBlocks(self):915 """916 Number of columns of blocks in the BlockMatrix.917 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),918 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])919 >>> mat = BlockMatrix(blocks, 3, 2)920 >>> mat.numColBlocks921 1922 """923 return self._java_matrix_wrapper.call("numColBlocks")924 def numRows(self):925 """926 Get or compute the number of rows.927 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),928 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])929 >>> mat = BlockMatrix(blocks, 3, 2)930 >>> print(mat.numRows())931 6932 >>> mat = BlockMatrix(blocks, 3, 2, 7, 6)933 >>> print(mat.numRows())934 7935 """936 return self._java_matrix_wrapper.call("numRows")937 def numCols(self):938 """939 Get or compute the number of cols.940 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),941 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])942 >>> mat = BlockMatrix(blocks, 3, 2)943 >>> print(mat.numCols())944 2945 >>> mat = BlockMatrix(blocks, 3, 2, 7, 6)946 >>> print(mat.numCols())947 6948 """949 return self._java_matrix_wrapper.call("numCols")950 @since('2.0.0')951 def cache(self):952 """953 Caches the underlying RDD.954 """955 self._java_matrix_wrapper.call("cache")956 return self957 @since('2.0.0')958 def persist(self, storageLevel):959 """960 Persists the underlying RDD with the specified storage level.961 """962 if not isinstance(storageLevel, StorageLevel):963 raise TypeError("`storageLevel` should be a StorageLevel, got %s" % type(storageLevel))964 javaStorageLevel = self._java_matrix_wrapper._sc._getJavaStorageLevel(storageLevel)965 self._java_matrix_wrapper.call("persist", javaStorageLevel)966 return self967 @since('2.0.0')968 def validate(self):969 """970 Validates the block matrix info against the matrix data (`blocks`)971 and throws an exception if any error is found.972 """973 self._java_matrix_wrapper.call("validate")974 def add(self, other):975 """976 Adds two block matrices together. The matrices must have the977 same size and matching `rowsPerBlock` and `colsPerBlock` values.978 If one of the sub matrix blocks that are being added is a979 SparseMatrix, the resulting sub matrix block will also be a980 SparseMatrix, even if it is being added to a DenseMatrix. If981 two dense sub matrix blocks are added, the output block will982 also be a DenseMatrix.983 >>> dm1 = Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])984 >>> dm2 = Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12])985 >>> sm = Matrices.sparse(3, 2, [0, 1, 3], [0, 1, 2], [7, 11, 12])986 >>> blocks1 = sc.parallelize([((0, 0), dm1), ((1, 0), dm2)])987 >>> blocks2 = sc.parallelize([((0, 0), dm1), ((1, 0), dm2)])988 >>> blocks3 = sc.parallelize([((0, 0), sm), ((1, 0), dm2)])989 >>> mat1 = BlockMatrix(blocks1, 3, 2)990 >>> mat2 = BlockMatrix(blocks2, 3, 2)991 >>> mat3 = BlockMatrix(blocks3, 3, 2)992 >>> mat1.add(mat2).toLocalMatrix()993 DenseMatrix(6, 2, [2.0, 4.0, 6.0, 14.0, 16.0, 18.0, 8.0, 10.0, 12.0, 20.0, 22.0, 24.0], 0)994 >>> mat1.add(mat3).toLocalMatrix()995 DenseMatrix(6, 2, [8.0, 2.0, 3.0, 14.0, 16.0, 18.0, 4.0, 16.0, 18.0, 20.0, 22.0, 24.0], 0)996 """997 if not isinstance(other, BlockMatrix):998 raise TypeError("Other should be a BlockMatrix, got %s" % type(other))999 other_java_block_matrix = other._java_matrix_wrapper._java_model1000 java_block_matrix = self._java_matrix_wrapper.call("add", other_java_block_matrix)1001 return BlockMatrix(java_block_matrix, self.rowsPerBlock, self.colsPerBlock)1002 @since('2.0.0')1003 def subtract(self, other):1004 """1005 Subtracts the given block matrix `other` from this block matrix:1006 `this - other`. The matrices must have the same size and1007 matching `rowsPerBlock` and `colsPerBlock` values. If one of1008 the sub matrix blocks that are being subtracted is a1009 SparseMatrix, the resulting sub matrix block will also be a1010 SparseMatrix, even if it is being subtracted from a DenseMatrix.1011 If two dense sub matrix blocks are subtracted, the output block1012 will also be a DenseMatrix.1013 >>> dm1 = Matrices.dense(3, 2, [3, 1, 5, 4, 6, 2])1014 >>> dm2 = Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12])1015 >>> sm = Matrices.sparse(3, 2, [0, 1, 3], [0, 1, 2], [1, 2, 3])1016 >>> blocks1 = sc.parallelize([((0, 0), dm1), ((1, 0), dm2)])1017 >>> blocks2 = sc.parallelize([((0, 0), dm2), ((1, 0), dm1)])1018 >>> blocks3 = sc.parallelize([((0, 0), sm), ((1, 0), dm2)])1019 >>> mat1 = BlockMatrix(blocks1, 3, 2)1020 >>> mat2 = BlockMatrix(blocks2, 3, 2)1021 >>> mat3 = BlockMatrix(blocks3, 3, 2)1022 >>> mat1.subtract(mat2).toLocalMatrix()1023 DenseMatrix(6, 2, [-4.0, -7.0, -4.0, 4.0, 7.0, 4.0, -6.0, -5.0, -10.0, 6.0, 5.0, 10.0], 0)1024 >>> mat2.subtract(mat3).toLocalMatrix()1025 DenseMatrix(6, 2, [6.0, 8.0, 9.0, -4.0, -7.0, -4.0, 10.0, 9.0, 9.0, -6.0, -5.0, -10.0], 0)1026 """1027 if not isinstance(other, BlockMatrix):1028 raise TypeError("Other should be a BlockMatrix, got %s" % type(other))1029 other_java_block_matrix = other._java_matrix_wrapper._java_model1030 java_block_matrix = self._java_matrix_wrapper.call("subtract", other_java_block_matrix)1031 return BlockMatrix(java_block_matrix, self.rowsPerBlock, self.colsPerBlock)1032 def multiply(self, other):1033 """1034 Left multiplies this BlockMatrix by `other`, another1035 BlockMatrix. The `colsPerBlock` of this matrix must equal the1036 `rowsPerBlock` of `other`. If `other` contains any SparseMatrix1037 blocks, they will have to be converted to DenseMatrix blocks.1038 The output BlockMatrix will only consist of DenseMatrix blocks.1039 This may cause some performance issues until support for1040 multiplying two sparse matrices is added.1041 >>> dm1 = Matrices.dense(2, 3, [1, 2, 3, 4, 5, 6])1042 >>> dm2 = Matrices.dense(2, 3, [7, 8, 9, 10, 11, 12])1043 >>> dm3 = Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])1044 >>> dm4 = Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12])1045 >>> sm = Matrices.sparse(3, 2, [0, 1, 3], [0, 1, 2], [7, 11, 12])1046 >>> blocks1 = sc.parallelize([((0, 0), dm1), ((0, 1), dm2)])1047 >>> blocks2 = sc.parallelize([((0, 0), dm3), ((1, 0), dm4)])1048 >>> blocks3 = sc.parallelize([((0, 0), sm), ((1, 0), dm4)])1049 >>> mat1 = BlockMatrix(blocks1, 2, 3)1050 >>> mat2 = BlockMatrix(blocks2, 3, 2)1051 >>> mat3 = BlockMatrix(blocks3, 3, 2)1052 >>> mat1.multiply(mat2).toLocalMatrix()1053 DenseMatrix(2, 2, [242.0, 272.0, 350.0, 398.0], 0)1054 >>> mat1.multiply(mat3).toLocalMatrix()1055 DenseMatrix(2, 2, [227.0, 258.0, 394.0, 450.0], 0)1056 """1057 if not isinstance(other, BlockMatrix):1058 raise TypeError("Other should be a BlockMatrix, got %s" % type(other))1059 other_java_block_matrix = other._java_matrix_wrapper._java_model1060 java_block_matrix = self._java_matrix_wrapper.call("multiply", other_java_block_matrix)1061 return BlockMatrix(java_block_matrix, self.rowsPerBlock, self.colsPerBlock)1062 @since('2.0.0')1063 def transpose(self):1064 """1065 Transpose this BlockMatrix. Returns a new BlockMatrix1066 instance sharing the same underlying data. Is a lazy operation.1067 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),1068 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])1069 >>> mat = BlockMatrix(blocks, 3, 2)1070 >>> mat_transposed = mat.transpose()1071 >>> mat_transposed.toLocalMatrix()1072 DenseMatrix(2, 6, [1.0, 4.0, 2.0, 5.0, 3.0, 6.0, 7.0, 10.0, 8.0, 11.0, 9.0, 12.0], 0)1073 """1074 java_transposed_matrix = self._java_matrix_wrapper.call("transpose")1075 return BlockMatrix(java_transposed_matrix, self.colsPerBlock, self.rowsPerBlock)1076 def toLocalMatrix(self):1077 """1078 Collect the distributed matrix on the driver as a DenseMatrix.1079 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),1080 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])1081 >>> mat = BlockMatrix(blocks, 3, 2).toLocalMatrix()1082 >>> # This BlockMatrix will have 6 effective rows, due to1083 >>> # having two sub-matrix blocks stacked, each with 3 rows.1084 >>> # The ensuing DenseMatrix will also have 6 rows.1085 >>> print(mat.numRows)1086 61087 >>> # This BlockMatrix will have 2 effective columns, due to1088 >>> # having two sub-matrix blocks stacked, each with 21089 >>> # columns. The ensuing DenseMatrix will also have 2 columns.1090 >>> print(mat.numCols)1091 21092 """1093 return self._java_matrix_wrapper.call("toLocalMatrix")1094 def toIndexedRowMatrix(self):1095 """1096 Convert this matrix to an IndexedRowMatrix.1097 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(3, 2, [1, 2, 3, 4, 5, 6])),1098 ... ((1, 0), Matrices.dense(3, 2, [7, 8, 9, 10, 11, 12]))])1099 >>> mat = BlockMatrix(blocks, 3, 2).toIndexedRowMatrix()1100 >>> # This BlockMatrix will have 6 effective rows, due to1101 >>> # having two sub-matrix blocks stacked, each with 3 rows.1102 >>> # The ensuing IndexedRowMatrix will also have 6 rows.1103 >>> print(mat.numRows())1104 61105 >>> # This BlockMatrix will have 2 effective columns, due to1106 >>> # having two sub-matrix blocks stacked, each with 2 columns.1107 >>> # The ensuing IndexedRowMatrix will also have 2 columns.1108 >>> print(mat.numCols())1109 21110 """1111 java_indexed_row_matrix = self._java_matrix_wrapper.call("toIndexedRowMatrix")1112 return IndexedRowMatrix(java_indexed_row_matrix)1113 def toCoordinateMatrix(self):1114 """1115 Convert this matrix to a CoordinateMatrix.1116 >>> blocks = sc.parallelize([((0, 0), Matrices.dense(1, 2, [1, 2])),1117 ... ((1, 0), Matrices.dense(1, 2, [7, 8]))])1118 >>> mat = BlockMatrix(blocks, 1, 2).toCoordinateMatrix()1119 >>> mat.entries.take(3)1120 [MatrixEntry(0, 0, 1.0), MatrixEntry(0, 1, 2.0), MatrixEntry(1, 0, 7.0)]1121 """1122 java_coordinate_matrix = self._java_matrix_wrapper.call("toCoordinateMatrix")1123 return CoordinateMatrix(java_coordinate_matrix)1124def _test():1125 import doctest1126 import numpy1127 from pyspark.sql import SparkSession1128 from pyspark.mllib.linalg import Matrices1129 import pyspark.mllib.linalg.distributed1130 try:1131 # Numpy 1.14+ changed it's string format.1132 numpy.set_printoptions(legacy='1.13')1133 except TypeError:1134 pass1135 globs = pyspark.mllib.linalg.distributed.__dict__.copy()1136 spark = SparkSession.builder\1137 .master("local[2]")\1138 .appName("mllib.linalg.distributed tests")\1139 .getOrCreate()1140 globs['sc'] = spark.sparkContext1141 globs['Matrices'] = Matrices1142 (failure_count, test_count) = doctest.testmod(globs=globs, optionflags=doctest.ELLIPSIS)1143 spark.stop()1144 if failure_count:1145 sys.exit(-1)1146if __name__ == "__main__":...
J3DIMath.js
Source:J3DIMath.js
1/*2 * Copyright (C) 2009 Apple Inc. All Rights Reserved.3 *4 * Redistribution and use in source and binary forms, with or without5 * modification, are permitted provided that the following conditions6 * are met:7 * 1. Redistributions of source code must retain the above copyright8 * notice, this list of conditions and the following disclaimer.9 * 2. Redistributions in binary form must reproduce the above copyright10 * notice, this list of conditions and the following disclaimer in the11 * documentation and/or other materials provided with the distribution.12 *13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24 */25 // J3DI (Jedi) - A support library for WebGL.26/*27 J3DI Math Classes. Currently includes:28 J3DIMatrix4 - A 4x4 Matrix29*/30/*31 J3DIMatrix4 class32 This class implements a 4x4 matrix. It has functions which duplicate the33 functionality of the OpenGL matrix stack and glut functions. On browsers34 that support it, CSSMatrix is used to accelerate operations.35 IDL:36 [37 Constructor(in J3DIMatrix4 matrix), // copy passed matrix into new J3DIMatrix438 Constructor(in sequence<float> array) // create new J3DIMatrix4 with 16 floats (row major)39 Constructor() // create new J3DIMatrix4 with identity matrix40 ]41 interface J3DIMatrix4 {42 void load(in J3DIMatrix4 matrix); // copy the values from the passed matrix43 void load(in sequence<float> array); // copy 16 floats into the matrix44 sequence<float> getAsArray(); // return the matrix as an array of 16 floats45 Float32Array getAsFloat32Array(); // return the matrix as a Float32Array with 16 values46 void setUniform(in WebGLRenderingContext ctx, // Send the matrix to the passed uniform location in the passed context47 in WebGLUniformLocation loc,48 in boolean transpose);49 void makeIdentity(); // replace the matrix with identity50 void transpose(); // replace the matrix with its transpose51 void invert(); // replace the matrix with its inverse52 void translate(in float x, in float y, in float z); // multiply the matrix by passed translation values on the right53 void translate(in J3DVector3 v); // multiply the matrix by passed translation values on the right54 void scale(in float x, in float y, in float z); // multiply the matrix by passed scale values on the right55 void scale(in J3DVector3 v); // multiply the matrix by passed scale values on the right56 void rotate(in float angle, // multiply the matrix by passed rotation values on the right57 in float x, in float y, in float z); // (angle is in degrees)58 void rotate(in float angle, in J3DVector3 v); // multiply the matrix by passed rotation values on the right59 // (angle is in degrees)60 void multiply(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the right61 void divide(in float divisor); // divide the matrix by the passed divisor62 void ortho(in float left, in float right, // multiply the matrix by the passed ortho values on the right63 in float bottom, in float top,64 in float near, in float far);65 void frustum(in float left, in float right, // multiply the matrix by the passed frustum values on the right66 in float bottom, in float top,67 in float near, in float far);68 void perspective(in float fovy, in float aspect, // multiply the matrix by the passed perspective values on the right69 in float zNear, in float zFar);70 void lookat(in J3DVector3 eye, // multiply the matrix by the passed lookat71 in J3DVector3 center, in J3DVector3 up); // values on the right72 bool decompose(in J3DVector3 translate, // decompose the matrix into the passed vector73 in J3DVector3 rotate,74 in J3DVector3 scale,75 in J3DVector3 skew,76 in sequence<float> perspective);77 }78 [79 Constructor(in J3DVector3 vector), // copy passed vector into new J3DVector380 Constructor(in sequence<float> array) // create new J3DVector3 with 3 floats from array81 Constructor(in float x, in float y, in float z) // create new J3DVector3 with 3 floats82 Constructor() // create new J3DVector3 with (0,0,0)83 ]84 interface J3DVector3 {85 void load(in J3DVector3 vector); // copy the values from the passed vector86 void load(in sequence<float> array); // copy 3 floats into the vector from array87 void load(in float x, in float y, in float z); // copy 3 floats into the vector88 sequence<float> getAsArray(); // return the vector as an array of 3 floats89 Float32Array getAsFloat32Array(); // return the matrix as a Float32Array with 16 values90 void multMatrix(in J3DIMatrix4 matrix); // multiply the vector by the passed matrix (on the right)91 float vectorLength(); // return the length of the vector92 float dot(); // return the dot product of the vector93 void cross(in J3DVector3 v); // replace the vector with vector x v94 void divide(in float divisor); // divide the vector by the passed divisor95 }96*/97J3DIHasCSSMatrix = false;98J3DIHasCSSMatrixCopy = false;99/*100if ("WebKitCSSMatrix" in window && ("media" in window && window.media.matchMedium("(-webkit-transform-3d)")) ||101 ("styleMedia" in window && window.styleMedia.matchMedium("(-webkit-transform-3d)"))) {102 J3DIHasCSSMatrix = true;103 if ("copy" in WebKitCSSMatrix.prototype)104 J3DIHasCSSMatrixCopy = true;105}106*/107// console.log("J3DIHasCSSMatrix="+J3DIHasCSSMatrix);108// console.log("J3DIHasCSSMatrixCopy="+J3DIHasCSSMatrixCopy);109//110// J3DIMatrix4111//112J3DIMatrix4 = function(m)113{114 if (J3DIHasCSSMatrix)115 this.$matrix = new WebKitCSSMatrix;116 else117 this.$matrix = new Object;118 if (typeof m == 'object') {119 if ("length" in m && m.length >= 16) {120 this.load(m);121 return;122 }123 else if (m instanceof J3DIMatrix4) {124 this.load(m);125 return;126 }127 }128 this.makeIdentity();129}130J3DIMatrix4.prototype.load = function()131{132 if (arguments.length == 1 && typeof arguments[0] == 'object') {133 var matrix;134 if (arguments[0] instanceof J3DIMatrix4) {135 matrix = arguments[0].$matrix;136 this.$matrix.m11 = matrix.m11;137 this.$matrix.m12 = matrix.m12;138 this.$matrix.m13 = matrix.m13;139 this.$matrix.m14 = matrix.m14;140 this.$matrix.m21 = matrix.m21;141 this.$matrix.m22 = matrix.m22;142 this.$matrix.m23 = matrix.m23;143 this.$matrix.m24 = matrix.m24;144 this.$matrix.m31 = matrix.m31;145 this.$matrix.m32 = matrix.m32;146 this.$matrix.m33 = matrix.m33;147 this.$matrix.m34 = matrix.m34;148 this.$matrix.m41 = matrix.m41;149 this.$matrix.m42 = matrix.m42;150 this.$matrix.m43 = matrix.m43;151 this.$matrix.m44 = matrix.m44;152 return;153 }154 else155 matrix = arguments[0];156 if ("length" in matrix && matrix.length >= 16) {157 this.$matrix.m11 = matrix[0];158 this.$matrix.m12 = matrix[1];159 this.$matrix.m13 = matrix[2];160 this.$matrix.m14 = matrix[3];161 this.$matrix.m21 = matrix[4];162 this.$matrix.m22 = matrix[5];163 this.$matrix.m23 = matrix[6];164 this.$matrix.m24 = matrix[7];165 this.$matrix.m31 = matrix[8];166 this.$matrix.m32 = matrix[9];167 this.$matrix.m33 = matrix[10];168 this.$matrix.m34 = matrix[11];169 this.$matrix.m41 = matrix[12];170 this.$matrix.m42 = matrix[13];171 this.$matrix.m43 = matrix[14];172 this.$matrix.m44 = matrix[15];173 return;174 }175 }176 this.makeIdentity();177}178J3DIMatrix4.prototype.getAsArray = function()179{180 return [181 this.$matrix.m11, this.$matrix.m12, this.$matrix.m13, this.$matrix.m14,182 this.$matrix.m21, this.$matrix.m22, this.$matrix.m23, this.$matrix.m24,183 this.$matrix.m31, this.$matrix.m32, this.$matrix.m33, this.$matrix.m34,184 this.$matrix.m41, this.$matrix.m42, this.$matrix.m43, this.$matrix.m44185 ];186}187J3DIMatrix4.prototype.getAsFloat32Array = function()188{189 if (J3DIHasCSSMatrixCopy) {190 var array = new Float32Array(16);191 this.$matrix.copy(array);192 return array;193 }194 return new Float32Array(this.getAsArray());195}196J3DIMatrix4.prototype.setUniform = function(ctx, loc, transpose)197{198 if (J3DIMatrix4.setUniformArray == undefined) {199 J3DIMatrix4.setUniformWebGLArray = new Float32Array(16);200 J3DIMatrix4.setUniformArray = new Array(16);201 }202 if (J3DIHasCSSMatrixCopy)203 this.$matrix.copy(J3DIMatrix4.setUniformWebGLArray);204 else {205 J3DIMatrix4.setUniformArray[0] = this.$matrix.m11;206 J3DIMatrix4.setUniformArray[1] = this.$matrix.m12;207 J3DIMatrix4.setUniformArray[2] = this.$matrix.m13;208 J3DIMatrix4.setUniformArray[3] = this.$matrix.m14;209 J3DIMatrix4.setUniformArray[4] = this.$matrix.m21;210 J3DIMatrix4.setUniformArray[5] = this.$matrix.m22;211 J3DIMatrix4.setUniformArray[6] = this.$matrix.m23;212 J3DIMatrix4.setUniformArray[7] = this.$matrix.m24;213 J3DIMatrix4.setUniformArray[8] = this.$matrix.m31;214 J3DIMatrix4.setUniformArray[9] = this.$matrix.m32;215 J3DIMatrix4.setUniformArray[10] = this.$matrix.m33;216 J3DIMatrix4.setUniformArray[11] = this.$matrix.m34;217 J3DIMatrix4.setUniformArray[12] = this.$matrix.m41;218 J3DIMatrix4.setUniformArray[13] = this.$matrix.m42;219 J3DIMatrix4.setUniformArray[14] = this.$matrix.m43;220 J3DIMatrix4.setUniformArray[15] = this.$matrix.m44;221 J3DIMatrix4.setUniformWebGLArray.set(J3DIMatrix4.setUniformArray);222 }223 ctx.uniformMatrix4fv(loc, transpose, J3DIMatrix4.setUniformWebGLArray);224}225J3DIMatrix4.prototype.makeIdentity = function()226{227 this.$matrix.m11 = 1;228 this.$matrix.m12 = 0;229 this.$matrix.m13 = 0;230 this.$matrix.m14 = 0;231 this.$matrix.m21 = 0;232 this.$matrix.m22 = 1;233 this.$matrix.m23 = 0;234 this.$matrix.m24 = 0;235 this.$matrix.m31 = 0;236 this.$matrix.m32 = 0;237 this.$matrix.m33 = 1;238 this.$matrix.m34 = 0;239 this.$matrix.m41 = 0;240 this.$matrix.m42 = 0;241 this.$matrix.m43 = 0;242 this.$matrix.m44 = 1;243}244J3DIMatrix4.prototype.transpose = function()245{246 var tmp = this.$matrix.m12;247 this.$matrix.m12 = this.$matrix.m21;248 this.$matrix.m21 = tmp;249 tmp = this.$matrix.m13;250 this.$matrix.m13 = this.$matrix.m31;251 this.$matrix.m31 = tmp;252 tmp = this.$matrix.m14;253 this.$matrix.m14 = this.$matrix.m41;254 this.$matrix.m41 = tmp;255 tmp = this.$matrix.m23;256 this.$matrix.m23 = this.$matrix.m32;257 this.$matrix.m32 = tmp;258 tmp = this.$matrix.m24;259 this.$matrix.m24 = this.$matrix.m42;260 this.$matrix.m42 = tmp;261 tmp = this.$matrix.m34;262 this.$matrix.m34 = this.$matrix.m43;263 this.$matrix.m43 = tmp;264}265J3DIMatrix4.prototype.invert = function()266{267 if (J3DIHasCSSMatrix) {268 this.$matrix = this.$matrix.inverse();269 return;270 }271 // Calculate the 4x4 determinant272 // If the determinant is zero,273 // then the inverse matrix is not unique.274 var det = this._determinant4x4();275 if (Math.abs(det) < 1e-8)276 return null;277 this._makeAdjoint();278 // Scale the adjoint matrix to get the inverse279 this.$matrix.m11 /= det;280 this.$matrix.m12 /= det;281 this.$matrix.m13 /= det;282 this.$matrix.m14 /= det;283 this.$matrix.m21 /= det;284 this.$matrix.m22 /= det;285 this.$matrix.m23 /= det;286 this.$matrix.m24 /= det;287 this.$matrix.m31 /= det;288 this.$matrix.m32 /= det;289 this.$matrix.m33 /= det;290 this.$matrix.m34 /= det;291 this.$matrix.m41 /= det;292 this.$matrix.m42 /= det;293 this.$matrix.m43 /= det;294 this.$matrix.m44 /= det;295}296J3DIMatrix4.prototype.translate = function(x,y,z)297{298 if (typeof x == 'object' && "length" in x) {299 var t = x;300 x = t[0];301 y = t[1];302 z = t[2];303 }304 else {305 if (x == undefined)306 x = 0;307 if (y == undefined)308 y = 0;309 if (z == undefined)310 z = 0;311 }312 if (J3DIHasCSSMatrix) {313 this.$matrix = this.$matrix.translate(x, y, z);314 return;315 }316 var matrix = new J3DIMatrix4();317 matrix.$matrix.m41 = x;318 matrix.$matrix.m42 = y;319 matrix.$matrix.m43 = z;320 this.multiply(matrix);321}322J3DIMatrix4.prototype.scale = function(x,y,z)323{324 if (typeof x == 'object' && "length" in x) {325 var t = x;326 x = t[0];327 y = t[1];328 z = t[2];329 }330 else {331 if (x == undefined)332 x = 1;333 if (z == undefined) {334 if (y == undefined) {335 y = x;336 z = x;337 }338 else339 z = 1;340 }341 else if (y == undefined)342 y = x;343 }344 if (J3DIHasCSSMatrix) {345 this.$matrix = this.$matrix.scale(x, y, z);346 return;347 }348 var matrix = new J3DIMatrix4();349 matrix.$matrix.m11 = x;350 matrix.$matrix.m22 = y;351 matrix.$matrix.m33 = z;352 this.multiply(matrix);353}354J3DIMatrix4.prototype.rotate = function(angle,x,y,z)355{356 // Forms are (angle, x,y,z), (angle,vector), (angleX, angleY, angleZ), (angle)357 if (typeof x == 'object' && "length" in x) {358 var t = x;359 x = t[0];360 y = t[1];361 z = t[2];362 }363 else {364 if (arguments.length == 1) {365 x = 0;366 y = 0;367 z = 1;368 }369 else if (arguments.length == 3) {370 this.rotate(angle, 1,0,0); // about X axis371 this.rotate(x, 0,1,0); // about Y axis372 this.rotate(y, 0,0,1); // about Z axis373 return;374 }375 }376 if (J3DIHasCSSMatrix) {377 this.$matrix = this.$matrix.rotateAxisAngle(x, y, z, angle);378 return;379 }380 // angles are in degrees. Switch to radians381 angle = angle / 180 * Math.PI;382 angle /= 2;383 var sinA = Math.sin(angle);384 var cosA = Math.cos(angle);385 var sinA2 = sinA * sinA;386 // normalize387 var len = Math.sqrt(x * x + y * y + z * z);388 if (len == 0) {389 // bad vector, just use something reasonable390 x = 0;391 y = 0;392 z = 1;393 } else if (len != 1) {394 x /= len;395 y /= len;396 z /= len;397 }398 var mat = new J3DIMatrix4();399 // optimize case where axis is along major axis400 if (x == 1 && y == 0 && z == 0) {401 mat.$matrix.m11 = 1;402 mat.$matrix.m12 = 0;403 mat.$matrix.m13 = 0;404 mat.$matrix.m21 = 0;405 mat.$matrix.m22 = 1 - 2 * sinA2;406 mat.$matrix.m23 = 2 * sinA * cosA;407 mat.$matrix.m31 = 0;408 mat.$matrix.m32 = -2 * sinA * cosA;409 mat.$matrix.m33 = 1 - 2 * sinA2;410 mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0;411 mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0;412 mat.$matrix.m44 = 1;413 } else if (x == 0 && y == 1 && z == 0) {414 mat.$matrix.m11 = 1 - 2 * sinA2;415 mat.$matrix.m12 = 0;416 mat.$matrix.m13 = -2 * sinA * cosA;417 mat.$matrix.m21 = 0;418 mat.$matrix.m22 = 1;419 mat.$matrix.m23 = 0;420 mat.$matrix.m31 = 2 * sinA * cosA;421 mat.$matrix.m32 = 0;422 mat.$matrix.m33 = 1 - 2 * sinA2;423 mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0;424 mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0;425 mat.$matrix.m44 = 1;426 } else if (x == 0 && y == 0 && z == 1) {427 mat.$matrix.m11 = 1 - 2 * sinA2;428 mat.$matrix.m12 = 2 * sinA * cosA;429 mat.$matrix.m13 = 0;430 mat.$matrix.m21 = -2 * sinA * cosA;431 mat.$matrix.m22 = 1 - 2 * sinA2;432 mat.$matrix.m23 = 0;433 mat.$matrix.m31 = 0;434 mat.$matrix.m32 = 0;435 mat.$matrix.m33 = 1;436 mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0;437 mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0;438 mat.$matrix.m44 = 1;439 } else {440 var x2 = x*x;441 var y2 = y*y;442 var z2 = z*z;443 mat.$matrix.m11 = 1 - 2 * (y2 + z2) * sinA2;444 mat.$matrix.m12 = 2 * (x * y * sinA2 + z * sinA * cosA);445 mat.$matrix.m13 = 2 * (x * z * sinA2 - y * sinA * cosA);446 mat.$matrix.m21 = 2 * (y * x * sinA2 - z * sinA * cosA);447 mat.$matrix.m22 = 1 - 2 * (z2 + x2) * sinA2;448 mat.$matrix.m23 = 2 * (y * z * sinA2 + x * sinA * cosA);449 mat.$matrix.m31 = 2 * (z * x * sinA2 + y * sinA * cosA);450 mat.$matrix.m32 = 2 * (z * y * sinA2 - x * sinA * cosA);451 mat.$matrix.m33 = 1 - 2 * (x2 + y2) * sinA2;452 mat.$matrix.m14 = mat.$matrix.m24 = mat.$matrix.m34 = 0;453 mat.$matrix.m41 = mat.$matrix.m42 = mat.$matrix.m43 = 0;454 mat.$matrix.m44 = 1;455 }456 this.multiply(mat);457}458J3DIMatrix4.prototype.multiply = function(mat)459{460 if (J3DIHasCSSMatrix) {461 this.$matrix = this.$matrix.multiply(mat.$matrix);462 return;463 }464 var m11 = (mat.$matrix.m11 * this.$matrix.m11 + mat.$matrix.m12 * this.$matrix.m21465 + mat.$matrix.m13 * this.$matrix.m31 + mat.$matrix.m14 * this.$matrix.m41);466 var m12 = (mat.$matrix.m11 * this.$matrix.m12 + mat.$matrix.m12 * this.$matrix.m22467 + mat.$matrix.m13 * this.$matrix.m32 + mat.$matrix.m14 * this.$matrix.m42);468 var m13 = (mat.$matrix.m11 * this.$matrix.m13 + mat.$matrix.m12 * this.$matrix.m23469 + mat.$matrix.m13 * this.$matrix.m33 + mat.$matrix.m14 * this.$matrix.m43);470 var m14 = (mat.$matrix.m11 * this.$matrix.m14 + mat.$matrix.m12 * this.$matrix.m24471 + mat.$matrix.m13 * this.$matrix.m34 + mat.$matrix.m14 * this.$matrix.m44);472 var m21 = (mat.$matrix.m21 * this.$matrix.m11 + mat.$matrix.m22 * this.$matrix.m21473 + mat.$matrix.m23 * this.$matrix.m31 + mat.$matrix.m24 * this.$matrix.m41);474 var m22 = (mat.$matrix.m21 * this.$matrix.m12 + mat.$matrix.m22 * this.$matrix.m22475 + mat.$matrix.m23 * this.$matrix.m32 + mat.$matrix.m24 * this.$matrix.m42);476 var m23 = (mat.$matrix.m21 * this.$matrix.m13 + mat.$matrix.m22 * this.$matrix.m23477 + mat.$matrix.m23 * this.$matrix.m33 + mat.$matrix.m24 * this.$matrix.m43);478 var m24 = (mat.$matrix.m21 * this.$matrix.m14 + mat.$matrix.m22 * this.$matrix.m24479 + mat.$matrix.m23 * this.$matrix.m34 + mat.$matrix.m24 * this.$matrix.m44);480 var m31 = (mat.$matrix.m31 * this.$matrix.m11 + mat.$matrix.m32 * this.$matrix.m21481 + mat.$matrix.m33 * this.$matrix.m31 + mat.$matrix.m34 * this.$matrix.m41);482 var m32 = (mat.$matrix.m31 * this.$matrix.m12 + mat.$matrix.m32 * this.$matrix.m22483 + mat.$matrix.m33 * this.$matrix.m32 + mat.$matrix.m34 * this.$matrix.m42);484 var m33 = (mat.$matrix.m31 * this.$matrix.m13 + mat.$matrix.m32 * this.$matrix.m23485 + mat.$matrix.m33 * this.$matrix.m33 + mat.$matrix.m34 * this.$matrix.m43);486 var m34 = (mat.$matrix.m31 * this.$matrix.m14 + mat.$matrix.m32 * this.$matrix.m24487 + mat.$matrix.m33 * this.$matrix.m34 + mat.$matrix.m34 * this.$matrix.m44);488 var m41 = (mat.$matrix.m41 * this.$matrix.m11 + mat.$matrix.m42 * this.$matrix.m21489 + mat.$matrix.m43 * this.$matrix.m31 + mat.$matrix.m44 * this.$matrix.m41);490 var m42 = (mat.$matrix.m41 * this.$matrix.m12 + mat.$matrix.m42 * this.$matrix.m22491 + mat.$matrix.m43 * this.$matrix.m32 + mat.$matrix.m44 * this.$matrix.m42);492 var m43 = (mat.$matrix.m41 * this.$matrix.m13 + mat.$matrix.m42 * this.$matrix.m23493 + mat.$matrix.m43 * this.$matrix.m33 + mat.$matrix.m44 * this.$matrix.m43);494 var m44 = (mat.$matrix.m41 * this.$matrix.m14 + mat.$matrix.m42 * this.$matrix.m24495 + mat.$matrix.m43 * this.$matrix.m34 + mat.$matrix.m44 * this.$matrix.m44);496 this.$matrix.m11 = m11;497 this.$matrix.m12 = m12;498 this.$matrix.m13 = m13;499 this.$matrix.m14 = m14;500 this.$matrix.m21 = m21;501 this.$matrix.m22 = m22;502 this.$matrix.m23 = m23;503 this.$matrix.m24 = m24;504 this.$matrix.m31 = m31;505 this.$matrix.m32 = m32;506 this.$matrix.m33 = m33;507 this.$matrix.m34 = m34;508 this.$matrix.m41 = m41;509 this.$matrix.m42 = m42;510 this.$matrix.m43 = m43;511 this.$matrix.m44 = m44;512}513J3DIMatrix4.prototype.divide = function(divisor)514{515 this.$matrix.m11 /= divisor;516 this.$matrix.m12 /= divisor;517 this.$matrix.m13 /= divisor;518 this.$matrix.m14 /= divisor;519 this.$matrix.m21 /= divisor;520 this.$matrix.m22 /= divisor;521 this.$matrix.m23 /= divisor;522 this.$matrix.m24 /= divisor;523 this.$matrix.m31 /= divisor;524 this.$matrix.m32 /= divisor;525 this.$matrix.m33 /= divisor;526 this.$matrix.m34 /= divisor;527 this.$matrix.m41 /= divisor;528 this.$matrix.m42 /= divisor;529 this.$matrix.m43 /= divisor;530 this.$matrix.m44 /= divisor;531}532J3DIMatrix4.prototype.ortho = function(left, right, bottom, top, near, far)533{534 var tx = (left + right) / (left - right);535 var ty = (top + bottom) / (top - bottom);536 var tz = (far + near) / (far - near);537 var matrix = new J3DIMatrix4();538 matrix.$matrix.m11 = 2 / (left - right);539 matrix.$matrix.m12 = 0;540 matrix.$matrix.m13 = 0;541 matrix.$matrix.m14 = 0;542 matrix.$matrix.m21 = 0;543 matrix.$matrix.m22 = 2 / (top - bottom);544 matrix.$matrix.m23 = 0;545 matrix.$matrix.m24 = 0;546 matrix.$matrix.m31 = 0;547 matrix.$matrix.m32 = 0;548 matrix.$matrix.m33 = -2 / (far - near);549 matrix.$matrix.m34 = 0;550 matrix.$matrix.m41 = tx;551 matrix.$matrix.m42 = ty;552 matrix.$matrix.m43 = tz;553 matrix.$matrix.m44 = 1;554 this.multiply(matrix);555}556J3DIMatrix4.prototype.frustum = function(left, right, bottom, top, near, far)557{558 var matrix = new J3DIMatrix4();559 var A = (right + left) / (right - left);560 var B = (top + bottom) / (top - bottom);561 var C = -(far + near) / (far - near);562 var D = -(2 * far * near) / (far - near);563 matrix.$matrix.m11 = (2 * near) / (right - left);564 matrix.$matrix.m12 = 0;565 matrix.$matrix.m13 = 0;566 matrix.$matrix.m14 = 0;567 matrix.$matrix.m21 = 0;568 matrix.$matrix.m22 = 2 * near / (top - bottom);569 matrix.$matrix.m23 = 0;570 matrix.$matrix.m24 = 0;571 matrix.$matrix.m31 = A;572 matrix.$matrix.m32 = B;573 matrix.$matrix.m33 = C;574 matrix.$matrix.m34 = -1;575 matrix.$matrix.m41 = 0;576 matrix.$matrix.m42 = 0;577 matrix.$matrix.m43 = D;578 matrix.$matrix.m44 = 0;579 this.multiply(matrix);580}581J3DIMatrix4.prototype.perspective = function(fovy, aspect, zNear, zFar)582{583 var top = Math.tan(fovy * Math.PI / 360) * zNear;584 var bottom = -top;585 var left = aspect * bottom;586 var right = aspect * top;587 this.frustum(left, right, bottom, top, zNear, zFar);588}589J3DIMatrix4.prototype.lookat = function(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz)590{591 if (typeof eyez == 'object' && "length" in eyez) {592 var t = eyez;593 upx = t[0];594 upy = t[1];595 upz = t[2];596 t = eyey;597 centerx = t[0];598 centery = t[1];599 centerz = t[2];600 t = eyex;601 eyex = t[0];602 eyey = t[1];603 eyez = t[2];604 }605 var matrix = new J3DIMatrix4();606 // Make rotation matrix607 // Z vector608 var zx = eyex - centerx;609 var zy = eyey - centery;610 var zz = eyez - centerz;611 var mag = Math.sqrt(zx * zx + zy * zy + zz * zz);612 if (mag) {613 zx /= mag;614 zy /= mag;615 zz /= mag;616 }617 // Y vector618 var yx = upx;619 var yy = upy;620 var yz = upz;621 // X vector = Y cross Z622 xx = yy * zz - yz * zy;623 xy = -yx * zz + yz * zx;624 xz = yx * zy - yy * zx;625 // Recompute Y = Z cross X626 yx = zy * xz - zz * xy;627 yy = -zx * xz + zz * xx;628 yx = zx * xy - zy * xx;629 // cross product gives area of parallelogram, which is < 1.0 for630 // non-perpendicular unit-length vectors; so normalize x, y here631 mag = Math.sqrt(xx * xx + xy * xy + xz * xz);632 if (mag) {633 xx /= mag;634 xy /= mag;635 xz /= mag;636 }637 mag = Math.sqrt(yx * yx + yy * yy + yz * yz);638 if (mag) {639 yx /= mag;640 yy /= mag;641 yz /= mag;642 }643 matrix.$matrix.m11 = xx;644 matrix.$matrix.m12 = xy;645 matrix.$matrix.m13 = xz;646 matrix.$matrix.m14 = 0;647 matrix.$matrix.m21 = yx;648 matrix.$matrix.m22 = yy;649 matrix.$matrix.m23 = yz;650 matrix.$matrix.m24 = 0;651 matrix.$matrix.m31 = zx;652 matrix.$matrix.m32 = zy;653 matrix.$matrix.m33 = zz;654 matrix.$matrix.m34 = 0;655 matrix.$matrix.m41 = 0;656 matrix.$matrix.m42 = 0;657 matrix.$matrix.m43 = 0;658 matrix.$matrix.m44 = 1;659 matrix.translate(-eyex, -eyey, -eyez);660 this.multiply(matrix);661}662// Returns true on success, false otherwise. All params are Array objects663J3DIMatrix4.prototype.decompose = function(_translate, _rotate, _scale, _skew, _perspective)664{665 // Normalize the matrix.666 if (this.$matrix.m44 == 0)667 return false;668 // Gather the params669 var translate, rotate, scale, skew, perspective;670 var translate = (_translate == undefined || !("length" in _translate)) ? new J3DIVector3 : _translate;671 var rotate = (_rotate == undefined || !("length" in _rotate)) ? new J3DIVector3 : _rotate;672 var scale = (_scale == undefined || !("length" in _scale)) ? new J3DIVector3 : _scale;673 var skew = (_skew == undefined || !("length" in _skew)) ? new J3DIVector3 : _skew;674 var perspective = (_perspective == undefined || !("length" in _perspective)) ? new Array(4) : _perspective;675 var matrix = new J3DIMatrix4(this);676 matrix.divide(matrix.$matrix.m44);677 // perspectiveMatrix is used to solve for perspective, but it also provides678 // an easy way to test for singularity of the upper 3x3 component.679 var perspectiveMatrix = new J3DIMatrix4(matrix);680 perspectiveMatrix.$matrix.m14 = 0;681 perspectiveMatrix.$matrix.m24 = 0;682 perspectiveMatrix.$matrix.m34 = 0;683 perspectiveMatrix.$matrix.m44 = 1;684 if (perspectiveMatrix._determinant4x4() == 0)685 return false;686 // First, isolate perspective.687 if (matrix.$matrix.m14 != 0 || matrix.$matrix.m24 != 0 || matrix.$matrix.m34 != 0) {688 // rightHandSide is the right hand side of the equation.689 var rightHandSide = [ matrix.$matrix.m14, matrix.$matrix.m24, matrix.$matrix.m34, matrix.$matrix.m44 ];690 // Solve the equation by inverting perspectiveMatrix and multiplying691 // rightHandSide by the inverse.692 var inversePerspectiveMatrix = new J3DIMatrix4(perspectiveMatrix);693 inversePerspectiveMatrix.invert();694 var transposedInversePerspectiveMatrix = new J3DIMatrix4(inversePerspectiveMatrix);695 transposedInversePerspectiveMatrix.transpose();696 transposedInversePerspectiveMatrix.multVecMatrix(perspective, rightHandSide);697 // Clear the perspective partition698 matrix.$matrix.m14 = matrix.$matrix.m24 = matrix.$matrix.m34 = 0699 matrix.$matrix.m44 = 1;700 }701 else {702 // No perspective.703 perspective[0] = perspective[1] = perspective[2] = 0;704 perspective[3] = 1;705 }706 // Next take care of translation707 translate[0] = matrix.$matrix.m41708 matrix.$matrix.m41 = 0709 translate[1] = matrix.$matrix.m42710 matrix.$matrix.m42 = 0711 translate[2] = matrix.$matrix.m43712 matrix.$matrix.m43 = 0713 // Now get scale and shear. 'row' is a 3 element array of 3 component vectors714 var row0 = new J3DIVector3(matrix.$matrix.m11, matrix.$matrix.m12, matrix.$matrix.m13);715 var row1 = new J3DIVector3(matrix.$matrix.m21, matrix.$matrix.m22, matrix.$matrix.m23);716 var row2 = new J3DIVector3(matrix.$matrix.m31, matrix.$matrix.m32, matrix.$matrix.m33);717 // Compute X scale factor and normalize first row.718 scale[0] = row0.vectorLength();719 row0.divide(scale[0]);720 // Compute XY shear factor and make 2nd row orthogonal to 1st.721 skew[0] = row0.dot(row1);722 row1.combine(row0, 1.0, -skew[0]);723 // Now, compute Y scale and normalize 2nd row.724 scale[1] = row1.vectorLength();725 row1.divide(scale[1]);726 skew[0] /= scale[1];727 // Compute XZ and YZ shears, orthogonalize 3rd row728 skew[1] = row1.dot(row2);729 row2.combine(row0, 1.0, -skew[1]);730 skew[2] = row1.dot(row2);731 row2.combine(row1, 1.0, -skew[2]);732 // Next, get Z scale and normalize 3rd row.733 scale[2] = row2.vectorLength();734 row2.divide(scale[2]);735 skew[1] /= scale[2];736 skew[2] /= scale[2];737 // At this point, the matrix (in rows) is orthonormal.738 // Check for a coordinate system flip. If the determinant739 // is -1, then negate the matrix and the scaling factors.740 var pdum3 = new J3DIVector3(row1);741 pdum3.cross(row2);742 if (row0.dot(pdum3) < 0) {743 for (i = 0; i < 3; i++) {744 scale[i] *= -1;745 row[0][i] *= -1;746 row[1][i] *= -1;747 row[2][i] *= -1;748 }749 }750 // Now, get the rotations out751 rotate[1] = Math.asin(-row0[2]);752 if (Math.cos(rotate[1]) != 0) {753 rotate[0] = Math.atan2(row1[2], row2[2]);754 rotate[2] = Math.atan2(row0[1], row0[0]);755 }756 else {757 rotate[0] = Math.atan2(-row2[0], row1[1]);758 rotate[2] = 0;759 }760 // Convert rotations to degrees761 var rad2deg = 180 / Math.PI;762 rotate[0] *= rad2deg;763 rotate[1] *= rad2deg;764 rotate[2] *= rad2deg;765 return true;766}767J3DIMatrix4.prototype._determinant2x2 = function(a, b, c, d)768{769 return a * d - b * c;770}771J3DIMatrix4.prototype._determinant3x3 = function(a1, a2, a3, b1, b2, b3, c1, c2, c3)772{773 return a1 * this._determinant2x2(b2, b3, c2, c3)774 - b1 * this._determinant2x2(a2, a3, c2, c3)775 + c1 * this._determinant2x2(a2, a3, b2, b3);776}777J3DIMatrix4.prototype._determinant4x4 = function()778{779 var a1 = this.$matrix.m11;780 var b1 = this.$matrix.m12;781 var c1 = this.$matrix.m13;782 var d1 = this.$matrix.m14;783 var a2 = this.$matrix.m21;784 var b2 = this.$matrix.m22;785 var c2 = this.$matrix.m23;786 var d2 = this.$matrix.m24;787 var a3 = this.$matrix.m31;788 var b3 = this.$matrix.m32;789 var c3 = this.$matrix.m33;790 var d3 = this.$matrix.m34;791 var a4 = this.$matrix.m41;792 var b4 = this.$matrix.m42;793 var c4 = this.$matrix.m43;794 var d4 = this.$matrix.m44;795 return a1 * this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)796 - b1 * this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)797 + c1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)798 - d1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);799}800J3DIMatrix4.prototype._makeAdjoint = function()801{802 var a1 = this.$matrix.m11;803 var b1 = this.$matrix.m12;804 var c1 = this.$matrix.m13;805 var d1 = this.$matrix.m14;806 var a2 = this.$matrix.m21;807 var b2 = this.$matrix.m22;808 var c2 = this.$matrix.m23;809 var d2 = this.$matrix.m24;810 var a3 = this.$matrix.m31;811 var b3 = this.$matrix.m32;812 var c3 = this.$matrix.m33;813 var d3 = this.$matrix.m34;814 var a4 = this.$matrix.m41;815 var b4 = this.$matrix.m42;816 var c4 = this.$matrix.m43;817 var d4 = this.$matrix.m44;818 // Row column labeling reversed since we transpose rows & columns819 this.$matrix.m11 = this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);820 this.$matrix.m21 = - this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);821 this.$matrix.m31 = this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);822 this.$matrix.m41 = - this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);823 this.$matrix.m12 = - this._determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);824 this.$matrix.m22 = this._determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);825 this.$matrix.m32 = - this._determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);826 this.$matrix.m42 = this._determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);827 this.$matrix.m13 = this._determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);828 this.$matrix.m23 = - this._determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);829 this.$matrix.m33 = this._determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);830 this.$matrix.m43 = - this._determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);831 this.$matrix.m14 = - this._determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);832 this.$matrix.m24 = this._determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);833 this.$matrix.m34 = - this._determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);834 this.$matrix.m44 = this._determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);835}836//837// J3DIVector3838//839J3DIVector3 = function(x,y,z)840{841 this.load(x,y,z);842}843J3DIVector3.prototype.load = function(x,y,z)844{845 if (typeof x == 'object' && "length" in x) {846 this[0] = x[0];847 this[1] = x[1];848 this[2] = x[2];849 }850 else if (typeof x == 'number') {851 this[0] = x;852 this[1] = y;853 this[2] = z;854 }855 else {856 this[0] = 0;857 this[1] = 0;858 this[2] = 0;859 }860}861J3DIVector3.prototype.getAsArray = function()862{863 return [ this[0], this[1], this[2] ];864}865J3DIVector3.prototype.getAsFloat32Array = function()866{867 return new Float32Array(this.getAsArray());868}869J3DIVector3.prototype.vectorLength = function()870{871 return Math.sqrt(this[0] * this[0] + this[1] * this[1] + this[2] * this[2]);872}873J3DIVector3.prototype.divide = function(divisor)874{875 this[0] /= divisor; this[1] /= divisor; this[2] /= divisor;876}877J3DIVector3.prototype.cross = function(v)878{879 this[0] = this[1] * v[2] - this[2] * v[1];880 this[1] = -this[0] * v[2] + this[2] * v[0];881 this[2] = this[0] * v[1] - this[1] * v[0];882}883J3DIVector3.prototype.dot = function(v)884{885 return this[0] * v[0] + this[1] * v[1] + this[2] * v[2];886}887J3DIVector3.prototype.combine = function(v, ascl, bscl)888{889 this[0] = (ascl * this[0]) + (bscl * v[0]);890 this[1] = (ascl * this[1]) + (bscl * v[1]);891 this[2] = (ascl * this[2]) + (bscl * v[2]);892}893J3DIVector3.prototype.multVecMatrix = function(matrix)894{895 var x = this[0];896 var y = this[1];897 var z = this[2];898 this[0] = matrix.$matrix.m41 + x * matrix.$matrix.m11 + y * matrix.$matrix.m21 + z * matrix.$matrix.m31;899 this[1] = matrix.$matrix.m42 + x * matrix.$matrix.m12 + y * matrix.$matrix.m22 + z * matrix.$matrix.m32;900 this[2] = matrix.$matrix.m43 + x * matrix.$matrix.m13 + y * matrix.$matrix.m23 + z * matrix.$matrix.m33;901 var w = matrix.$matrix.m44 + x * matrix.$matrix.m14 + y * matrix.$matrix.m24 + z * matrix.$matrix.m34;902 if (w != 1 && w != 0) {903 this[0] /= w;904 this[1] /= w;905 this[2] /= w;906 }907}908J3DIVector3.prototype.toString = function()909{910 return "["+this[0]+","+this[1]+","+this[2]+"]";...
TransformMatrix.js
Source:TransformMatrix.js
...806 */807 getCSSMatrix: function ()808 {809 var m = this.matrix;810 return 'matrix(' + m[0] + ',' + m[1] + ',' + m[2] + ',' + m[3] + ',' + m[4] + ',' + m[5] + ')';811 },812 /**813 * Destroys this Transform Matrix.814 *815 * @method Phaser.GameObjects.Components.TransformMatrix#destroy816 * @since 3.4.0817 */818 destroy: function ()819 {820 this.matrix = null;821 this.decomposedMatrix = null;822 }823});824module.exports = TransformMatrix;
ModelViewProjection.js
Source:ModelViewProjection.js
1/**2 * @author Richard Davey <rich@photonstorm.com>3 * @copyright 2020 Photon Storm Ltd.4 * @license {@link https://opensource.org/licenses/MIT|MIT License}5 */6/**7 * Implements a model view projection matrices.8 * Pipelines can implement this for doing 2D and 3D rendering.9 *10 * @namespace Phaser.Renderer.WebGL.Pipelines.ModelViewProjection11 * @since 3.0.012 */13var ModelViewProjection = {14 /**15 * Dirty flag for checking if model matrix needs to be updated on GPU.16 * 17 * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelMatrixDirty18 * @type {boolean}19 * @since 3.0.020 */21 modelMatrixDirty: false,22 /**23 * Dirty flag for checking if view matrix needs to be updated on GPU.24 * 25 * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewMatrixDirty26 * @type {boolean}27 * @since 3.0.028 */29 viewMatrixDirty: false,30 /**31 * Dirty flag for checking if projection matrix needs to be updated on GPU.32 * 33 * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projectionMatrixDirty34 * @type {boolean}35 * @since 3.0.036 */37 projectionMatrixDirty: false,38 /**39 * Model matrix40 * 41 * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelMatrix42 * @type {?Float32Array}43 * @since 3.0.044 */45 modelMatrix: null,46 /**47 * View matrix48 * 49 * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewMatrix50 * @type {?Float32Array}51 * @since 3.0.052 */53 viewMatrix: null,54 /**55 * Projection matrix56 * 57 * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projectionMatrix58 * @type {?Float32Array}59 * @since 3.0.060 */61 projectionMatrix: null,62 /**63 * Initializes MVP matrices with an identity matrix64 * 65 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#mvpInit66 * @since 3.0.067 */68 mvpInit: function ()69 {70 this.modelMatrixDirty = true;71 this.viewMatrixDirty = true;72 this.projectionMatrixDirty = true;73 74 this.modelMatrix = new Float32Array([75 1, 0, 0, 0,76 0, 1, 0, 0,77 0, 0, 1, 0,78 0, 0, 0, 179 ]);80 81 this.viewMatrix = new Float32Array([82 1, 0, 0, 0,83 0, 1, 0, 0,84 0, 0, 1, 0,85 0, 0, 0, 186 ]);87 88 this.projectionMatrix = new Float32Array([89 1, 0, 0, 0,90 0, 1, 0, 0,91 0, 0, 1, 0,92 0, 0, 0, 193 ]);94 95 return this;96 },97 /**98 * If dirty flags are set then the matrices are uploaded to the GPU.99 * 100 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#mvpUpdate101 * @since 3.0.0102 */103 mvpUpdate: function ()104 {105 var program = this.program;106 if (this.modelMatrixDirty)107 {108 this.renderer.setMatrix4(program, 'uModelMatrix', false, this.modelMatrix);109 this.modelMatrixDirty = false;110 }111 112 if (this.viewMatrixDirty)113 {114 this.renderer.setMatrix4(program, 'uViewMatrix', false, this.viewMatrix);115 this.viewMatrixDirty = false;116 }117 if (this.projectionMatrixDirty)118 {119 this.renderer.setMatrix4(program, 'uProjectionMatrix', false, this.projectionMatrix);120 this.projectionMatrixDirty = false;121 }122 return this;123 },124 /**125 * Loads an identity matrix to the model matrix126 * 127 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelIdentity128 * @since 3.0.0129 */130 modelIdentity: function ()131 {132 var modelMatrix = this.modelMatrix;133 134 modelMatrix[0] = 1;135 modelMatrix[1] = 0;136 modelMatrix[2] = 0;137 modelMatrix[3] = 0;138 modelMatrix[4] = 0;139 modelMatrix[5] = 1;140 modelMatrix[6] = 0;141 modelMatrix[7] = 0;142 modelMatrix[8] = 0;143 modelMatrix[9] = 0;144 modelMatrix[10] = 1;145 modelMatrix[11] = 0;146 modelMatrix[12] = 0;147 modelMatrix[13] = 0;148 modelMatrix[14] = 0;149 modelMatrix[15] = 1;150 this.modelMatrixDirty = true;151 152 return this;153 },154 /**155 * Scale model matrix156 * 157 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelScale158 * @since 3.0.0159 *160 * @param {number} x - The x component.161 * @param {number} y - The y component.162 * @param {number} z - The z component.163 *164 * @return {this} This Model View Projection.165 */166 modelScale: function (x, y, z)167 {168 var modelMatrix = this.modelMatrix;169 modelMatrix[0] = modelMatrix[0] * x;170 modelMatrix[1] = modelMatrix[1] * x;171 modelMatrix[2] = modelMatrix[2] * x;172 modelMatrix[3] = modelMatrix[3] * x;173 modelMatrix[4] = modelMatrix[4] * y;174 modelMatrix[5] = modelMatrix[5] * y;175 modelMatrix[6] = modelMatrix[6] * y;176 modelMatrix[7] = modelMatrix[7] * y;177 modelMatrix[8] = modelMatrix[8] * z;178 modelMatrix[9] = modelMatrix[9] * z;179 modelMatrix[10] = modelMatrix[10] * z;180 modelMatrix[11] = modelMatrix[11] * z;181 182 this.modelMatrixDirty = true;183 return this;184 },185 /**186 * Translate model matrix187 * 188 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelTranslate189 * @since 3.0.0190 *191 * @param {number} x - The x component.192 * @param {number} y - The y component.193 * @param {number} z - The z component.194 *195 * @return {this} This Model View Projection.196 */197 modelTranslate: function (x, y, z)198 {199 var modelMatrix = this.modelMatrix;200 modelMatrix[12] = modelMatrix[0] * x + modelMatrix[4] * y + modelMatrix[8] * z + modelMatrix[12];201 modelMatrix[13] = modelMatrix[1] * x + modelMatrix[5] * y + modelMatrix[9] * z + modelMatrix[13];202 modelMatrix[14] = modelMatrix[2] * x + modelMatrix[6] * y + modelMatrix[10] * z + modelMatrix[14];203 modelMatrix[15] = modelMatrix[3] * x + modelMatrix[7] * y + modelMatrix[11] * z + modelMatrix[15];204 this.modelMatrixDirty = true;205 return this;206 },207 /**208 * Rotates the model matrix in the X axis.209 * 210 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelRotateX211 * @since 3.0.0212 *213 * @param {number} radians - The amount to rotate by.214 *215 * @return {this} This Model View Projection.216 */217 modelRotateX: function (radians)218 {219 var modelMatrix = this.modelMatrix;220 var s = Math.sin(radians);221 var c = Math.cos(radians);222 var a10 = modelMatrix[4];223 var a11 = modelMatrix[5];224 var a12 = modelMatrix[6];225 var a13 = modelMatrix[7];226 var a20 = modelMatrix[8];227 var a21 = modelMatrix[9];228 var a22 = modelMatrix[10];229 var a23 = modelMatrix[11];230 modelMatrix[4] = a10 * c + a20 * s;231 modelMatrix[5] = a11 * c + a21 * s;232 modelMatrix[6] = a12 * c + a22 * s;233 modelMatrix[7] = a13 * c + a23 * s;234 modelMatrix[8] = a20 * c - a10 * s;235 modelMatrix[9] = a21 * c - a11 * s;236 modelMatrix[10] = a22 * c - a12 * s;237 modelMatrix[11] = a23 * c - a13 * s;238 this.modelMatrixDirty = true;239 return this;240 },241 /**242 * Rotates the model matrix in the Y axis.243 * 244 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelRotateY245 * @since 3.0.0246 *247 * @param {number} radians - The amount to rotate by.248 *249 * @return {this} This Model View Projection.250 */251 modelRotateY: function (radians)252 {253 var modelMatrix = this.modelMatrix;254 var s = Math.sin(radians);255 var c = Math.cos(radians);256 var a00 = modelMatrix[0];257 var a01 = modelMatrix[1];258 var a02 = modelMatrix[2];259 var a03 = modelMatrix[3];260 var a20 = modelMatrix[8];261 var a21 = modelMatrix[9];262 var a22 = modelMatrix[10];263 var a23 = modelMatrix[11];264 modelMatrix[0] = a00 * c - a20 * s;265 modelMatrix[1] = a01 * c - a21 * s;266 modelMatrix[2] = a02 * c - a22 * s;267 modelMatrix[3] = a03 * c - a23 * s;268 modelMatrix[8] = a00 * s + a20 * c;269 modelMatrix[9] = a01 * s + a21 * c;270 modelMatrix[10] = a02 * s + a22 * c;271 modelMatrix[11] = a03 * s + a23 * c;272 this.modelMatrixDirty = true;273 274 return this;275 },276 277 /**278 * Rotates the model matrix in the Z axis.279 * 280 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelRotateZ281 * @since 3.0.0282 *283 * @param {number} radians - The amount to rotate by.284 *285 * @return {this} This Model View Projection.286 */287 modelRotateZ: function (radians)288 {289 var modelMatrix = this.modelMatrix;290 var s = Math.sin(radians);291 var c = Math.cos(radians);292 var a00 = modelMatrix[0];293 var a01 = modelMatrix[1];294 var a02 = modelMatrix[2];295 var a03 = modelMatrix[3];296 var a10 = modelMatrix[4];297 var a11 = modelMatrix[5];298 var a12 = modelMatrix[6];299 var a13 = modelMatrix[7];300 modelMatrix[0] = a00 * c + a10 * s;301 modelMatrix[1] = a01 * c + a11 * s;302 modelMatrix[2] = a02 * c + a12 * s;303 modelMatrix[3] = a03 * c + a13 * s;304 modelMatrix[4] = a10 * c - a00 * s;305 modelMatrix[5] = a11 * c - a01 * s;306 modelMatrix[6] = a12 * c - a02 * s;307 modelMatrix[7] = a13 * c - a03 * s;308 this.modelMatrixDirty = true;309 return this;310 },311 /**312 * Loads identity matrix into the view matrix313 * 314 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewIdentity315 * @since 3.0.0316 *317 * @return {this} This Model View Projection.318 */319 viewIdentity: function ()320 {321 var viewMatrix = this.viewMatrix;322 323 viewMatrix[0] = 1;324 viewMatrix[1] = 0;325 viewMatrix[2] = 0;326 viewMatrix[3] = 0;327 viewMatrix[4] = 0;328 viewMatrix[5] = 1;329 viewMatrix[6] = 0;330 viewMatrix[7] = 0;331 viewMatrix[8] = 0;332 viewMatrix[9] = 0;333 viewMatrix[10] = 1;334 viewMatrix[11] = 0;335 viewMatrix[12] = 0;336 viewMatrix[13] = 0;337 viewMatrix[14] = 0;338 viewMatrix[15] = 1;339 this.viewMatrixDirty = true;340 341 return this;342 },343 344 /**345 * Scales view matrix346 * 347 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewScale348 * @since 3.0.0349 *350 * @param {number} x - The x component.351 * @param {number} y - The y component.352 * @param {number} z - The z component.353 *354 * @return {this} This Model View Projection.355 */356 viewScale: function (x, y, z)357 {358 var viewMatrix = this.viewMatrix;359 viewMatrix[0] = viewMatrix[0] * x;360 viewMatrix[1] = viewMatrix[1] * x;361 viewMatrix[2] = viewMatrix[2] * x;362 viewMatrix[3] = viewMatrix[3] * x;363 viewMatrix[4] = viewMatrix[4] * y;364 viewMatrix[5] = viewMatrix[5] * y;365 viewMatrix[6] = viewMatrix[6] * y;366 viewMatrix[7] = viewMatrix[7] * y;367 viewMatrix[8] = viewMatrix[8] * z;368 viewMatrix[9] = viewMatrix[9] * z;369 viewMatrix[10] = viewMatrix[10] * z;370 viewMatrix[11] = viewMatrix[11] * z;371 372 this.viewMatrixDirty = true;373 return this;374 },375 /**376 * Translates view matrix377 * 378 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewTranslate379 * @since 3.0.0380 *381 * @param {number} x - The x component.382 * @param {number} y - The y component.383 * @param {number} z - The z component.384 *385 * @return {this} This Model View Projection.386 */387 viewTranslate: function (x, y, z)388 {389 var viewMatrix = this.viewMatrix;390 viewMatrix[12] = viewMatrix[0] * x + viewMatrix[4] * y + viewMatrix[8] * z + viewMatrix[12];391 viewMatrix[13] = viewMatrix[1] * x + viewMatrix[5] * y + viewMatrix[9] * z + viewMatrix[13];392 viewMatrix[14] = viewMatrix[2] * x + viewMatrix[6] * y + viewMatrix[10] * z + viewMatrix[14];393 viewMatrix[15] = viewMatrix[3] * x + viewMatrix[7] * y + viewMatrix[11] * z + viewMatrix[15];394 this.viewMatrixDirty = true;395 return this;396 },397 398 /**399 * Rotates view matrix in the X axis.400 * 401 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewRotateX402 * @since 3.0.0403 *404 * @param {number} radians - The amount to rotate by.405 *406 * @return {this} This Model View Projection.407 */408 viewRotateX: function (radians)409 {410 var viewMatrix = this.viewMatrix;411 var s = Math.sin(radians);412 var c = Math.cos(radians);413 var a10 = viewMatrix[4];414 var a11 = viewMatrix[5];415 var a12 = viewMatrix[6];416 var a13 = viewMatrix[7];417 var a20 = viewMatrix[8];418 var a21 = viewMatrix[9];419 var a22 = viewMatrix[10];420 var a23 = viewMatrix[11];421 viewMatrix[4] = a10 * c + a20 * s;422 viewMatrix[5] = a11 * c + a21 * s;423 viewMatrix[6] = a12 * c + a22 * s;424 viewMatrix[7] = a13 * c + a23 * s;425 viewMatrix[8] = a20 * c - a10 * s;426 viewMatrix[9] = a21 * c - a11 * s;427 viewMatrix[10] = a22 * c - a12 * s;428 viewMatrix[11] = a23 * c - a13 * s;429 this.viewMatrixDirty = true;430 return this;431 },432 433 /**434 * Rotates view matrix in the Y axis.435 * 436 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewRotateY437 * @since 3.0.0438 *439 * @param {number} radians - The amount to rotate by.440 *441 * @return {this} This Model View Projection.442 */443 viewRotateY: function (radians)444 {445 var viewMatrix = this.viewMatrix;446 var s = Math.sin(radians);447 var c = Math.cos(radians);448 var a00 = viewMatrix[0];449 var a01 = viewMatrix[1];450 var a02 = viewMatrix[2];451 var a03 = viewMatrix[3];452 var a20 = viewMatrix[8];453 var a21 = viewMatrix[9];454 var a22 = viewMatrix[10];455 var a23 = viewMatrix[11];456 viewMatrix[0] = a00 * c - a20 * s;457 viewMatrix[1] = a01 * c - a21 * s;458 viewMatrix[2] = a02 * c - a22 * s;459 viewMatrix[3] = a03 * c - a23 * s;460 viewMatrix[8] = a00 * s + a20 * c;461 viewMatrix[9] = a01 * s + a21 * c;462 viewMatrix[10] = a02 * s + a22 * c;463 viewMatrix[11] = a03 * s + a23 * c;464 this.viewMatrixDirty = true;465 466 return this;467 },468 469 /**470 * Rotates view matrix in the Z axis.471 * 472 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewRotateZ473 * @since 3.0.0474 *475 * @param {number} radians - The amount to rotate by.476 *477 * @return {this} This Model View Projection.478 */479 viewRotateZ: function (radians)480 {481 var viewMatrix = this.viewMatrix;482 var s = Math.sin(radians);483 var c = Math.cos(radians);484 var a00 = viewMatrix[0];485 var a01 = viewMatrix[1];486 var a02 = viewMatrix[2];487 var a03 = viewMatrix[3];488 var a10 = viewMatrix[4];489 var a11 = viewMatrix[5];490 var a12 = viewMatrix[6];491 var a13 = viewMatrix[7];492 viewMatrix[0] = a00 * c + a10 * s;493 viewMatrix[1] = a01 * c + a11 * s;494 viewMatrix[2] = a02 * c + a12 * s;495 viewMatrix[3] = a03 * c + a13 * s;496 viewMatrix[4] = a10 * c - a00 * s;497 viewMatrix[5] = a11 * c - a01 * s;498 viewMatrix[6] = a12 * c - a02 * s;499 viewMatrix[7] = a13 * c - a03 * s;500 this.viewMatrixDirty = true;501 return this;502 },503 /**504 * Loads a 2D view matrix (3x2 matrix) into a 4x4 view matrix 505 * 506 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewLoad2D507 * @since 3.0.0508 *509 * @param {Float32Array} matrix2D - The Matrix2D.510 *511 * @return {this} This Model View Projection.512 */513 viewLoad2D: function (matrix2D)514 {515 var vm = this.viewMatrix;516 vm[0] = matrix2D[0];517 vm[1] = matrix2D[1];518 vm[2] = 0.0;519 vm[3] = 0.0;520 vm[4] = matrix2D[2];521 vm[5] = matrix2D[3];522 vm[6] = 0.0;523 vm[7] = 0.0;524 vm[8] = matrix2D[4];525 vm[9] = matrix2D[5];526 vm[10] = 1.0;527 vm[11] = 0.0;528 vm[12] = 0.0;529 vm[13] = 0.0;530 vm[14] = 0.0;531 vm[15] = 1.0;532 this.viewMatrixDirty = true;533 return this;534 },535 /**536 * Copies a 4x4 matrix into the view matrix537 * 538 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewLoad539 * @since 3.0.0540 *541 * @param {Float32Array} matrix - The Matrix2D.542 *543 * @return {this} This Model View Projection.544 */545 viewLoad: function (matrix)546 {547 var vm = this.viewMatrix;548 vm[0] = matrix[0];549 vm[1] = matrix[1];550 vm[2] = matrix[2];551 vm[3] = matrix[3];552 vm[4] = matrix[4];553 vm[5] = matrix[5];554 vm[6] = matrix[6];555 vm[7] = matrix[7];556 vm[8] = matrix[8];557 vm[9] = matrix[9];558 vm[10] = matrix[10];559 vm[11] = matrix[11];560 vm[12] = matrix[12];561 vm[13] = matrix[13];562 vm[14] = matrix[14];563 vm[15] = matrix[15];564 this.viewMatrixDirty = true;565 return this;566 },567 568 /**569 * Loads identity matrix into the projection matrix.570 * 571 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projIdentity572 * @since 3.0.0573 *574 * @return {this} This Model View Projection.575 */576 projIdentity: function ()577 {578 var projectionMatrix = this.projectionMatrix;579 580 projectionMatrix[0] = 1;581 projectionMatrix[1] = 0;582 projectionMatrix[2] = 0;583 projectionMatrix[3] = 0;584 projectionMatrix[4] = 0;585 projectionMatrix[5] = 1;586 projectionMatrix[6] = 0;587 projectionMatrix[7] = 0;588 projectionMatrix[8] = 0;589 projectionMatrix[9] = 0;590 projectionMatrix[10] = 1;591 projectionMatrix[11] = 0;592 projectionMatrix[12] = 0;593 projectionMatrix[13] = 0;594 projectionMatrix[14] = 0;595 projectionMatrix[15] = 1;596 this.projectionMatrixDirty = true;597 return this;598 },599 /**600 * Sets up an orthographic projection matrix601 * 602 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projOrtho603 * @since 3.0.0604 *605 * @param {number} left - The left value.606 * @param {number} right - The right value.607 * @param {number} bottom - The bottom value.608 * @param {number} top - The top value.609 * @param {number} near - The near value.610 * @param {number} far - The far value.611 *612 * @return {this} This Model View Projection.613 */614 projOrtho: function (left, right, bottom, top, near, far)615 {616 var projectionMatrix = this.projectionMatrix;617 var leftRight = 1.0 / (left - right);618 var bottomTop = 1.0 / (bottom - top);619 var nearFar = 1.0 / (near - far);620 projectionMatrix[0] = -2.0 * leftRight;621 projectionMatrix[1] = 0.0;622 projectionMatrix[2] = 0.0;623 projectionMatrix[3] = 0.0;624 projectionMatrix[4] = 0.0;625 projectionMatrix[5] = -2.0 * bottomTop;626 projectionMatrix[6] = 0.0;627 projectionMatrix[7] = 0.0;628 projectionMatrix[8] = 0.0;629 projectionMatrix[9] = 0.0;630 projectionMatrix[10] = 2.0 * nearFar;631 projectionMatrix[11] = 0.0;632 projectionMatrix[12] = (left + right) * leftRight;633 projectionMatrix[13] = (top + bottom) * bottomTop;634 projectionMatrix[14] = (far + near) * nearFar;635 projectionMatrix[15] = 1.0;636 this.projectionMatrixDirty = true;637 return this;638 },639 640 /**641 * Sets up a perspective projection matrix642 * 643 * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projPersp644 * @since 3.0.0645 *646 * @param {number} fovY - The fov value.647 * @param {number} aspectRatio - The aspectRatio value.648 * @param {number} near - The near value.649 * @param {number} far - The far value.650 *651 * @return {this} This Model View Projection.652 */653 projPersp: function (fovY, aspectRatio, near, far)654 {655 var projectionMatrix = this.projectionMatrix;656 var fov = 1.0 / Math.tan(fovY / 2.0);657 var nearFar = 1.0 / (near - far);658 659 projectionMatrix[0] = fov / aspectRatio;660 projectionMatrix[1] = 0.0;661 projectionMatrix[2] = 0.0;662 projectionMatrix[3] = 0.0;663 projectionMatrix[4] = 0.0;664 projectionMatrix[5] = fov;665 projectionMatrix[6] = 0.0;666 projectionMatrix[7] = 0.0;667 projectionMatrix[8] = 0.0;668 projectionMatrix[9] = 0.0;669 projectionMatrix[10] = (far + near) * nearFar;670 projectionMatrix[11] = -1.0;671 projectionMatrix[12] = 0.0;672 projectionMatrix[13] = 0.0;673 projectionMatrix[14] = (2.0 * far * near) * nearFar;674 projectionMatrix[15] = 0.0;675 676 this.projectionMatrixDirty = true;677 return this;678 }679};...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!