Source code: `Q-Matrix.js`

### Grid of numbers

A matrix is just a grid of numbers; rows and columns containing values. Matrices can be of any size. Here’s an example of a 3 × 2 matrix. It is 3 columns wide and 2 rows tall, containing the values 1 through 6.

 1 2 3 4 5 6

When describing the dimensions of a matrix we always specify the number of rows first, then the number of columns. The above is an example of a 3 × 2 matrix, while below is a matrix containing similar data, but in a 2 × 3 configuration.

 1 2 3 4 5 6

#### Order matters

Q thinks about matrices in row-major order. This means we read the values just as they are ordered above, starting with the top-most row, reading values from left to right, then proceeding to the next row down and repeating that process. Our choice of row-major order makes reading and writing matrix values more akin to reading and writing in English; easier to type and program here.

 1 2 3 4 5 6
Row-major order.
 1 3 5 2 4 6
Column-major order.

#### Vectors are slices

While a matrix is a two-dimensional grid of numbers, a vector is more like a slice of numbers—such as a “skinny” matrix that is only one column wide, or a “flat” matrix that is only one row high. Let’s look at some examples of matrices that are simultaneously vectors.

 1 2 3 4
Any “flat” matrix is
a row vector.
 1 2 3 4
Any “skinny” matrix is
a column vector.
 1 2 3 4
But matrices with
more than one column
or more than one row
are not vectors.

While the above 2 × 2 matrix is not a vector, you could say that it contains vectors: Two column vectors or two row vectors.

Because vectors are just a type of matrix we can add them, multiply them, and so on—just like any other matrix. Vectors will play a prominent role in defining qubits and expressing the state of a quantum circuit.

#### Complex numbers

Instead of just storing regular old numbers, our matrices are geared to store complex numbers. (This is because qubits are really just a pair of complex numbers that we store in a 1 × 2 matrix. So, yes—the example matrices above are actually all larger than qubits are!) In general, we don’t even have to think about the fact that our matrices are storing complex numbers because `Q.Matrix` is happy to accept regular JavaScript `Number` values as input—and `Q.ComplexNumber` will silently handle the conversion for us.

### Constructor

Matrix `Function([ size: Number ] or [ width: Number, height: Number ] or [ rows: arguments ]) => Q.Matrix`
The `Matrix` class creates and operates on matrices of arbitrary dimensions. This is in contrast to some popular graphics libraries which optimize for specific sizes of matrices—with corresponding class names like `Matrix3` (for 3 × 3 matrices) or `Matrix4` (for 4 × 4 matrices). Q, meanwhile, is much more flexible. The constructor expects an argument list of equal-length arrays where each array represents a row of column values. `Matrix` then automatically determines the dimensions based on the number of arguments (rows) and length of each row (number of columns). The constructor will throw an error if the row lengths are not equal.

Upon creation `Matrix` converts all argument values of type `Number` to `Q.ComplexNumber` instances. Currently `Matrix` does not support recursion; a matrix cannot contain matrices as values. A matrix also cannot change its dimensions, making destructive properties that yield matrices of a different size (like `multiply\$`, for example) impossible.

``````
var a = new Q.Matrix(
[ 1, 2, 3 ],
[ 4, 5, 6 ])
``````
 1 2 3 4 5 6
• rows
`Array` The list of supplied `arguments`.
• columns
`Array` The list of getters and setters that operate on the rows property to appear as if this property contained actual values.
• index
`Number` An identification number assigned to the instance, used for minding the total number of instances created.

#### Import and export formats

Getting data in and out of any system can be laborious. With that in mind, `Q.Matrix` comes with helper methods for importing and exporting the following common formats:

### Static properties

• help
`Function ⇒ String` Calls and returns the value of `Q.help`, passing `Q.Matrix` as the argument.
• index
`Number` The number of instances created so far.

#### Constants and constant creation

• constants
`Object` Constants are appended directly to the `Q.Matrix` object. For convenience they are also appended to this `Q.Matrix`.constants object to make looking up constants in the JavaScript console trivial, and to make iterating across all constants convenient via functions like `Object.entries`, `Object.keys`, `Object.values`, and so on. The intention that a property act as a constant is signaled by its labelling in all-uppercase.
• createConstant
`Function( key: String, value: * )` Appends a property named by `key` with a value of `value` to both the `Matrix` object and its `constants` property.
• createConstants
`Function( … )` Expects an even number of arguments. Will use each pair in the sequence of arguments to call `createConstant`.

#### Constants — Example matrices

• IDENTITY_2X2
`Q.Matrix` Initialized as `Q.Matrix.createIdentity( 2 )`. Described by the following matrix:
 1 0 0 1
• IDENTITY_3X3
`Q.Matrix` Initialized as `Q.Matrix.createIdentity( 3 )`. Described by the following matrix:
 1 0 0 0 1 0 0 0 1
• IDENTITY_4X4
`Q.Matrix` Initialized as `Q.Matrix.createIdentity( 4 )`. Described by the following matrix:
 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
• CONSTANT0_2X2
`Q.Matrix` Initialized as
``````
new Q.Matrix(
[ 1, 1 ],
[ 0, 0 ])
``````
Described by the following matrix:
 1 1 0 0
• CONSTANT1_2X2
`Q.Matrix` Initialized as
``````
new Q.Matrix(
[ 0, 0 ],
[ 1, 1 ])
``````
Described by the following matrix:
 0 0 1 1
• NEGATION_2X2
`Q.Matrix` Initialized as
``````
new Q.Matrix(
[ 0, 1 ],
[ 1, 0 ])
``````
Described by the following matrix:
 0 1 1 0
• TEST_MAP_9X9
`Q.Matrix` Initialized as
``````
new Q.Matrix(
[ 11, 21, 31, 41, 51, 61, 71, 81, 91 ],
[ 12, 22, 32, 42, 52, 62, 72, 82, 92 ],
[ 13, 23, 33, 43, 53, 63, 73, 83, 93 ],
[ 14, 24, 34, 44, 54, 64, 74, 84, 94 ],
[ 15, 25, 35, 45, 55, 65, 75, 85, 95 ],
[ 16, 26, 36, 46, 56, 66, 76, 86, 96 ],
[ 17, 27, 37, 47, 57, 67, 77, 87, 97 ],
[ 18, 28, 38, 48, 58, 68, 78, 88, 98 ],
[ 19, 29, 39, 49, 59, 69, 79, 89, 99 ])
``````
Described by the following matrix:
 11 21 31 41 51 61 71 81 91 12 22 32 42 52 62 72 82 92 13 23 33 43 53 63 73 83 93 14 24 34 44 54 64 74 84 94 15 25 35 45 55 65 75 85 95 16 26 36 46 56 66 76 86 96 17 27 37 47 57 67 77 87 97 18 28 38 48 58 68 78 88 98 19 29 39 49 59 69 79 89 99

#### Static inspection

• isMatrixLike
`Function( object: * ) ⇒ Boolean` Returns `true` if `object` is an instance of `Q.Matrix` or if `Q.Matrix` is in `object`’s prototype chain, otherwise returns `false`.
• getWidth
`Function( m: Q.Matrix ) ⇒ Number` Returns the number of columns in this matrix.
• getHeight
`Function( m: Q.Matrix ) ⇒ Number` Returns the number of rows in this matrix.
• haveEqualDimensions
`Function( a: Q.Matrix, b: Q.Matrix ) ⇒ Boolean` Returns `true` if both matrices have the same number of rows and the same number of columns, otherwise returns `false`.
• isWithinRange
`Function( n: Number, minimum: Number, maximum: Number ) ⇒ Boolean` Returns `true` if `n` is an integer, and is greater than or equal to `minimum`, and is less than or equal to `maximum`, otherwise returns `false`. Used to determine if a value is a valid row or column number.

#### Creation from description

• createSquare
`Function([ size: Number = 2[, f: Function = function(){ return 0 }]]) ⇒ Q.Matrix` Creates a square matrix of width and height equal to `size`. `f` is invoked for each cell of the matrix and is passed two arguments, `x: Number` and `y: Number`, which correspond to the address of the cell. The result of `f` is then assigned to that cell. Returns the resulting matrix.
• createZero
`Function( size: Number ) ⇒ Q.Matrix` Calls `createSquare` with the passed `size` argument, but no function argument, to yield a matrix of all zeros. Returns the resulting matrix.
• createOne
`Function( size: Number ) ⇒ Q.Matrix` Calls `createSquare` with the passed `size` argument, and an `f` argument that invariably returns `1`, to yield a matrix of all ones. Returns the resulting matrix.
• createIdentity
`Function( size: Number ) ⇒ Q.Matrix` Calls `createSquare` with the passed `size` argument, and an `f` argument that yields an identity matrix. Returns the resulting matrix.

#### Creation from data import

• fromArray
`Function( array: Array ) ⇒ Q.Matrix` Ingests matrix data from an `Array` of values where each element represents a row that is itself an `Array` of values, and returns the result. Note how this differs from the `Matrix` constructor which uses the function’s `Array`-like arguments list directly.
• fromXsv
`Function( input: String, rowSeparator: String, valueSeparator: String ) ⇒ Q.Matrix` Ingests matrix data from a `String` of values that are sepearated in to rows by `rowSeparator` and separated in to values (columns) by `valueSeparator`, and returns the result.
• fromCsv
`Function( csv: String ) ⇒ Q.Matrix` Ingests matrix data from a `String` of comma-separated-values and returns the result.
• fromTsv
`Function( tsv: String ) ⇒ Q.Matrix` Ingests matrix data from a `String` of tab-separated-values and returns the result.
• fromHtml
`Function( html: String ) ⇒ Q.Matrix` Ingests matrix data from a `String` of HTML table code and returns the result.

#### Static maths

`Function( a: Q.Matrix, b: Q.Matrix ) ⇒ Q.Matrix` Adds the two supplied matrices together and returns the result.
• multiplyScalar
`Function( a: Q.Matrix, b: Number ) ⇒ Q.Matrix` Multiplies the supplied matrix by the supplied scalar and returns the result.
• multiply
`Function( a: Q.Matrix, b: Q.Matrix ) ⇒ Q.Matrix` Multiplies the two supplied matrices together and returns the result.
• multiplyTensor
`Function( a: Q.Matrix, b: Q.Matrix ) ⇒ Q.Matrix` Returns the `tensor product` of the two supplied matrices.

### Prototype properties

#### Self inspection

• isValidRow
`Function( rowIndex: Number ) ⇒ Boolean` Returns true if `rowIndex` is greater than or equal to zero and is less than the height of this matrix, otherwise returns `false`. Will return a `Boolean` value, thereby halting “Fluent interface” method chaining for this instance.
• isValidColumn
`Function( columnIndex: Number ) ⇒ Boolean` Returns true if `columnIndex` is greater than or equal to zero and is less than the width of this matrix, otherwise returns `false`. Will return a `Boolean` value, thereby halting “Fluent interface” method chaining for this instance.
`Function( x: Number, y: Number ) ⇒ Boolean` Returns `true` if `x` is a valid row index and `y` is a valid column index, otherwise returns `false`. Will return a `Boolean` value, thereby halting “Fluent interface” method chaining for this instance.
• getWidth
`Function ⇒ Number` Calls and returns the value of `Q.Matrix.getWidth`, passing itself as the argument. Will return a `Number` value, thereby halting “Fluent interface” method chaining for this instance.
• getHeight
`Function ⇒ Number` Calls and returns the value of `Q.Matrix.getHeight`, passing itself as the argument. Will return a `Number` value, thereby halting “Fluent interface” method chaining for this instance.

#### Data export (non-destructive)

`Function( x: Number, y: Number ) ⇒ Q.ComplexNumber` Returns the value of this matrix’s cell at row `y` and column `x`. Equivalent to `this.columns[ x ][ y ]` or `this.rows[ y ][ x ]` but with safety mechanisms. Will return a `Number` value, thereby halting “Fluent interface” method chaining for this instance.
• clone
`Function ⇒ Q.Matrix` Returns a new instance with the value for `rows` copied from this instance. The constructor will populate the values for `columns` as well.
• toArray
`Function ⇒ Array` Returns the value of this instance’s `rows` property. Will return an `Array` value, thereby halting “Fluent interface” method chaining for this instance.
• toXsv
`Function( rowSeparator: String, valueSeparator: String ) ⇒ String` Returns the value of this matrix expressed as a `String` delimited by the supplied arguments. Will return a `String` value, thereby halting “Fluent interface” method chaining for this instance.
• toCsv
`Function ⇒ String` Creates a comma-separated-values table and returns it as a `String`. Will return a `String` value, thereby halting “Fluent interface” method chaining for this instance.
• toTsv
`Function ⇒ String` Creates a tab-separated-values table and returns it as a `String`. Will return a `String` value, thereby halting “Fluent interface” method chaining for this instance.
• toHtml
`Function ⇒ String` Creates HTML table code and returns it as a `String`. Will return a `String` value, thereby halting “Fluent interface” method chaining for this instance.
• toDom
`Function ⇒ DocumentFragment` Arriving soon. Will return a `DocumentFragment` value, thereby halting “Fluent interface” method chaining for this instance.

#### Data import (destructive)

• write\$
`Function( x: Number, y: Number, n: Number or Q.ComplexNumber ) ⇒ Q.Matrix` Writes a value, `n`, to the specified cell address of this matrix. Equivalent to `this.columns[ x ][ y ] = n`, or `this.rows[ y ][ x ] = n`, but with safety checks.
• copy\$
`Function( m: Q.Matrix ) ⇒ Q.Matrix` Copies the value for `rows` from the supplied argument, `m`, if `m` is a matrix of equal dimensions to this instance, otherwise returns `Q.error`.
• fromArray\$
`Function( array: Array ) ⇒ Q.Matrix` Passes the supplied `array` argument to the `fromArray` static method, then uses `copy\$` to copy that result in to this instance.
• fromCsv\$
`Function( csv: String ) ⇒ Q.Matrix` Passes the supplied `csv` argument to the `fromCsv` static method, then uses `copy\$` to copy that result in to this instance.
• fromTsv\$
`Function( tsv: String ) ⇒ Q.Matrix` Passes the supplied `tsv` argument to the `fromTsv` static method, then uses `copy\$` to copy that result in to this instance.
• fromHtml\$
`Function( html: String ) ⇒ Q.Matrix` Passes the supplied `html` argument to the `fromHtml` static method, then uses `copy\$` to copy that result in to this instance.

#### Maths operations (non-destructive)

`Function( otherMatrix: Q.Matrix ) ⇒ Q.Matrix` Passes this instance as the first argument and `otherMatrix` as the second argument to the `add` static method and returns the result.
• multiplyScalar
`Function( scalar: Number ) ⇒ Q.Matrix` Passes this instance as the first argument and `otherMatrix` as the second argument to the `multiplyScalar` static method and returns the result.
• multiply
`Function( otherMatrix: Q.Matrix ) ⇒ Q.Matrix` Passes this instance as the first argument and `otherMatrix` as the second argument to the `multiply` static method and returns the result.
• multiplyTensor
`Function( otherMatrix: Q.Matrix ) ⇒ Q.Matrix` Passes this instance as the first argument and `otherMatrix` as the second argument to the `multiplyTensor` static method and returns the result.

#### Maths operations (destructive)

`Function( otherMatrix: Q.Matrix ) ⇒ Q.Matrix` Calls the `add` instance method with `otherMatrix` as an argument and `copies` the result to this instance.
`Function( otherMatrix: Q.Matrix ) ⇒ Q.Matrix` Calls the `multiplyScalar` instance method with `otherMatrix` as an argument and `copies` the result to this instance.