tcuMatrix.js (11385B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ 20 'use strict'; 21 goog.provide('framework.common.tcuMatrix'); 22 goog.require('framework.delibs.debase.deMath'); 23 24 goog.scope(function() { 25 26 var tcuMatrix = framework.common.tcuMatrix; 27 var deMath = framework.delibs.debase.deMath; 28 29 var DE_ASSERT = function(x) { 30 if (!x) 31 throw new Error('Assert failed'); 32 }; 33 34 /** 35 * @constructor 36 * @param {number} rows 37 * @param {number} cols 38 * @param {*=} value 39 * Initialize to identity. 40 */ 41 tcuMatrix.Matrix = function(rows, cols, value) { 42 value = value == undefined ? 1 : value; 43 this.rows = rows; 44 this.cols = cols; 45 this.matrix = []; 46 for (var i = 0; i < cols; i++) 47 this.matrix[i] = []; 48 for (var row = 0; row < rows; row++) 49 for (var col = 0; col < cols; col++) 50 this.set(row, col, (row == col) ? value : 0); 51 }; 52 53 /** 54 * @param {number} rows 55 * @param {number} cols 56 * @param {Array<number>} vector 57 * @return {tcuMatrix.Matrix} 58 */ 59 tcuMatrix.matrixFromVector = function(rows, cols, vector) { 60 var matrix = new tcuMatrix.Matrix(rows, cols); 61 for (var row = 0; row < vector.length; row++) 62 for (var col = 0; col < vector.length; col++) 63 matrix.matrix[col][row] = row == col ? vector[row] : 0; 64 return matrix; 65 }; 66 67 /** 68 * @param {number} rows 69 * @param {number} cols 70 * @param {Array<number>} src 71 * @return {tcuMatrix.Matrix} 72 */ 73 tcuMatrix.matrixFromDataArray = function(rows, cols, src) { 74 var matrix = new tcuMatrix.Matrix(rows, cols); 75 for (var row = 0; row < rows; row++) { 76 for (var col = 0; col < cols; col++) { 77 matrix.matrix[col][row] = src[row * cols + col]; 78 } 79 } 80 return matrix; 81 }; 82 83 /** 84 * Fill the Matrix with data from array 85 * @param {number} rows 86 * @param {number} cols 87 * @param {Array<number>} array 88 * @return {tcuMatrix.Matrix} 89 */ 90 tcuMatrix.matrixFromArray = function(rows, cols, array) { 91 DE_ASSERT(array.length === rows * cols); 92 var matrix = new tcuMatrix.Matrix(rows, cols); 93 for (var row = 0; row < rows; row++) 94 for (var col = 0; col < cols; col++) 95 matrix.matrix[col][row] = array[row * cols + col]; 96 return matrix; 97 }; 98 99 tcuMatrix.Matrix.prototype.set = function(x, y, value) { 100 this.isRangeValid(x, y); 101 this.matrix[y][x] = value; 102 }; 103 104 tcuMatrix.Matrix.prototype.setRow = function(row, values) { 105 if (!deMath.deInBounds32(row, 0, this.rows)) 106 throw new Error('Rows out of range'); 107 if (values.length > this.cols) 108 throw new Error('Too many columns'); 109 for (var col = 0; col < values.length; col++) 110 this.matrix[col][row] = values[col]; 111 }; 112 113 tcuMatrix.Matrix.prototype.setCol = function(col, values) { 114 if (!deMath.deInBounds32(col, 0, this.cols)) 115 throw new Error('Columns out of range'); 116 if (values.length > this.rows) 117 throw new Error('Too many rows'); 118 for (var row = 0; row < values.length; row++) 119 this.matrix[col][row] = values[row]; 120 }; 121 122 tcuMatrix.Matrix.prototype.get = function(x, y) { 123 this.isRangeValid(x, y); 124 return this.matrix[y][x]; 125 }; 126 127 tcuMatrix.Matrix.prototype.getColumn = function(y) { 128 return this.matrix[y]; 129 }; 130 131 tcuMatrix.Matrix.prototype.isRangeValid = function(x, y) { 132 if (!deMath.deInBounds32(x, 0, this.rows)) 133 throw new Error('Rows out of range'); 134 if (!deMath.deInBounds32(y, 0, this.cols)) 135 throw new Error('Columns out of range'); 136 }; 137 138 /** 139 * @return {Array<number>} 140 */ 141 tcuMatrix.Matrix.prototype.getColumnMajorData = function() { 142 /** @type {Array<number>} */ var a = []; 143 for (var col = 0; col < this.cols; col++) 144 for (var row = 0; row < this.rows; row++) 145 a.push(this.get(row, col)); 146 return a; 147 }; 148 149 /** 150 * @param {tcuMatrix.Matrix} matrixA 151 * @param {tcuMatrix.Matrix} matrixB 152 * @return {tcuMatrix.Matrix} 153 */ 154 tcuMatrix.add = function(matrixA, matrixB) { 155 var res = new tcuMatrix.Matrix(matrixA.rows, matrixB.cols); 156 for (var col = 0; col < matrixA.cols; col++) 157 for (var row = 0; row < matrixA.rows; row++) 158 res.set(row, col, matrixA.get(row, col) + matrixB.get(row, col)); 159 return res; 160 }; 161 162 /** 163 * @param {tcuMatrix.Matrix} matrixA 164 * @param {tcuMatrix.Matrix} matrixB 165 * @return {tcuMatrix.Matrix} 166 */ 167 tcuMatrix.subtract = function(matrixA, matrixB) { 168 var res = new tcuMatrix.Matrix(matrixA.rows, matrixB.cols); 169 for (var col = 0; col < matrixA.cols; col++) 170 for (var row = 0; row < matrixA.rows; row++) 171 res.set(row, col, matrixA.get(row, col) - matrixB.get(row, col)); 172 return res; 173 }; 174 175 /** 176 * @param {tcuMatrix.Matrix} matrixA 177 * @param {tcuMatrix.Matrix} matrixB 178 * @return {tcuMatrix.Matrix} 179 * Multiplication of two matrices. 180 */ 181 tcuMatrix.multiply = function(matrixA, matrixB) { 182 if (matrixA.cols != matrixB.rows) 183 throw new Error('Wrong matrices sizes'); 184 var res = new tcuMatrix.Matrix(matrixA.rows, matrixB.cols); 185 for (var row = 0; row < matrixA.rows; row++) 186 for (var col = 0; col < matrixB.cols; col++) { 187 var v = 0; 188 for (var ndx = 0; ndx < matrixA.cols; ndx++) 189 v += matrixA.get(row, ndx) * matrixB.get(ndx, col); 190 res.set(row, col, v); 191 } 192 return res; 193 }; 194 195 /** 196 * @param {tcuMatrix.Matrix} matrixA 197 * @param {tcuMatrix.Matrix} matrixB 198 * @return {tcuMatrix.Matrix} 199 */ 200 tcuMatrix.divide = function(matrixA, matrixB) { 201 var res = new tcuMatrix.Matrix(matrixA.rows, matrixA.cols); 202 for (var col = 0; col < matrixA.cols; col++) 203 for (var row = 0; row < matrixA.rows; row++) 204 res.set(row, col, matrixA.get(row, col) / matrixB.get(row, col)); 205 return res; 206 }; 207 208 /** 209 * @param {tcuMatrix.Matrix} mtx 210 * @param {Array<number>} vec 211 * @return {Array<number>} 212 */ 213 tcuMatrix.multiplyMatVec = function(mtx, vec) { 214 /** @type {Array<number>} */ var res = []; 215 /** @type {number} */ var value; 216 for (var row = 0; row < mtx.rows; row++) { 217 value = 0; 218 for (var col = 0; col < mtx.cols; col++) 219 value += mtx.get(row, col) * vec[col]; 220 res[row] = value; 221 } 222 223 return res; 224 }; 225 226 /** 227 * @param {Array<number>} vec 228 * @param {tcuMatrix.Matrix} mtx 229 * @return {Array<number>} 230 */ 231 tcuMatrix.multiplyVecMat = function(vec, mtx) { 232 /** @type {Array<number>} */ var res = []; 233 /** @type {number} */ var value; 234 for (var col = 0; col < mtx.cols; col++) { 235 value = 0; 236 for (var row = 0; row < mtx.rows; row++) 237 value += mtx.get(row, col) * vec[row]; 238 res[col] = value; 239 } 240 241 return res; 242 }; 243 244 tcuMatrix.Matrix.prototype.toString = function() { 245 var str = 'mat' + this.cols; 246 if (this.rows !== this.cols) 247 str += 'x' + this.rows; 248 str += '('; 249 for (var col = 0; col < this.cols; col++) { 250 str += '['; 251 for (var row = 0; row < this.rows; row++) { 252 str += this.matrix[col][row]; 253 if (row != this.rows - 1) 254 str += ', '; 255 } 256 str += ']'; 257 258 if (col != this.cols - 1) 259 str += ', '; 260 } 261 str += ')'; 262 return str; 263 }; 264 265 /** 266 * @param {tcuMatrix.Matrix} mtx 267 * @param {number} scalar 268 * @return {tcuMatrix.Matrix} 269 */ 270 tcuMatrix.subtractMatScal = function(mtx, scalar) { 271 /** @type {tcuMatrix.Matrix} */ var res = new tcuMatrix.Matrix(mtx.rows, mtx.cols); 272 for (var col = 0; col < mtx.cols; col++) 273 for (var row = 0; row < mtx.rows; row++) 274 res.set(row, col, mtx.get(row, col) - scalar); 275 276 return res; 277 }; 278 279 /** 280 * @param {tcuMatrix.Matrix} mtx 281 * @param {number} scalar 282 * @return {tcuMatrix.Matrix} 283 */ 284 tcuMatrix.addMatScal = function(mtx, scalar) { 285 /** @type {tcuMatrix.Matrix} */ var res = new tcuMatrix.Matrix(mtx.rows, mtx.cols); 286 for (var col = 0; col < mtx.cols; col++) 287 for (var row = 0; row < mtx.rows; row++) 288 res.set(row, col, mtx.get(row, col) + scalar); 289 290 return res; 291 }; 292 293 /** 294 * @param {tcuMatrix.Matrix} mtx 295 * @param {number} scalar 296 * @return {tcuMatrix.Matrix} 297 */ 298 tcuMatrix.multiplyMatScal = function(mtx, scalar) { 299 /** @type {tcuMatrix.Matrix} */ var res = new tcuMatrix.Matrix(mtx.rows, mtx.cols); 300 for (var col = 0; col < mtx.cols; col++) 301 for (var row = 0; row < mtx.rows; row++) 302 res.set(row, col, mtx.get(row, col) * scalar); 303 304 return res; 305 }; 306 307 /** 308 * @param {tcuMatrix.Matrix} mtx 309 * @param {number} scalar 310 * @return {tcuMatrix.Matrix} 311 */ 312 tcuMatrix.divideMatScal = function(mtx, scalar) { 313 /** @type {tcuMatrix.Matrix} */ var res = new tcuMatrix.Matrix(mtx.rows, mtx.cols); 314 for (var col = 0; col < mtx.cols; col++) 315 for (var row = 0; row < mtx.rows; row++) 316 res.set(row, col, mtx.get(row, col) / scalar); 317 318 return res; 319 }; 320 321 /** 322 * @constructor 323 * @extends {tcuMatrix.Matrix} 324 */ 325 tcuMatrix.Mat2 = function() { 326 tcuMatrix.Matrix.call(this, 2, 2); 327 }; 328 329 tcuMatrix.Mat2.prototype = Object.create(tcuMatrix.Matrix.prototype); 330 tcuMatrix.Mat2.prototype.constructor = tcuMatrix.Mat2; 331 332 /** 333 * @constructor 334 * @extends {tcuMatrix.Matrix} 335 */ 336 tcuMatrix.Mat3 = function() { 337 tcuMatrix.Matrix.call(this, 3, 3); 338 }; 339 340 tcuMatrix.Mat3.prototype = Object.create(tcuMatrix.Matrix.prototype); 341 tcuMatrix.Mat3.prototype.constructor = tcuMatrix.Mat3; 342 343 /** 344 * @constructor 345 * @extends {tcuMatrix.Matrix} 346 */ 347 tcuMatrix.Mat4 = function() { 348 tcuMatrix.Matrix.call(this, 4, 4); 349 }; 350 351 tcuMatrix.Mat4.prototype = Object.create(tcuMatrix.Matrix.prototype); 352 tcuMatrix.Mat4.prototype.constructor = tcuMatrix.Mat4; 353 354 });