
net.algart.arrays.Matrix Maven / Gradle / Ivy
Show all versions of algart Show documentation
/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.algart.arrays;
import net.algart.math.*;
import java.util.List;
import java.util.Objects;
/**
* AlgART matrix: multidimensional array.
*
* Unlike {@link Array AlgART array}, AlgART matrix is a very simple thing.
* The matrix is just a pair:
*
*
* - a reference to any AlgART array, so-called built-in array of the matrix,
* that actually stores all matrix elements;
*
* - the set of dimensions: a little usual array of integers —
long[] dim
,
* describing the sizes of the multidimensional matrix in every dimension.
*
*
* The product of all dimensions must be equal to the array length. Moreover,
* the array must be {@link UpdatableArray#asUnresizable() unresizable}: so, the array length
* cannot be changed after creating the matrix.
*
* It is supposed that all matrix elements are stored in the built-in AlgART array.
* The storing scheme is traditional. For 2D matrix, the matrix element (x,y)
* is stored at the position y*dim[0]+x
of the array (dim[0]
is the first
* matrix dimension: the "width"). For 3D matrix, the matrix element (x,y,z)
* is stored at the position z*dim[1]*dim[0]+y*dim[0]+x
(dim[0]
is the
* x-dimension, dim[1] is the y-dimension). In the common case, the element of n
-dimensional matrix
* with coordinates i0,i1,...,in-1 is stored
* in the built-in array at the position
*
*
* in-1dn-2...d1d0 + ... +
* i2d1d0 +
* i1d0 + i0,
*
*
* where dk=dim[k]
(k=0,1,...,n-1
)
* is the dimension #k
.
*
* There are 3 basic ways to create a new matrix.
*
*
* - You may create a new zero-filled matrix with new allocated array by
* {@link MemoryModel#newMatrix(Class, Class, long...)}
* method or one of more concrete methods {@link MemoryModel#newByteMatrix(long...)},
* {@link MemoryModel#newShortMatrix(long...)}, etc.
*
* - You may create a matrix view of an existing array with the specified dimension set
* by {@link Matrices#matrix(Array, long...)} method.
*
* - You may replace built-in array of the matrix with a new one (with the same length)
* by {@link #matrix(Array)} method of the matrix instance;
* the new matrix instance will be created.
* It is the basic way to change some properties of the built-in array,
* for example, to convert it to {@link Array#asImmutable() immutable}
* or {@link Array#asCopyOnNextWrite() copy-on-next-write} form.
*
*
* We do not provide special tools for accessing matrix elements by several indexes,
* as "getByte(x,y)" or similar methods. But there is the {@link #index(long...) index}
* method, that transforms a set of multidimensional indexes
* i0, i2, ..., in-1
* into the position in the corresponded array, as described above.
* Also you can get a reference to the built-in array by the {@link #array()} method.
* The typical example of access to matrix elements is the following:
*
*
* Matrix<UpdatableFloatArray> m = ...;
* m.array().setFloat(m.index(x, y, z), myValue);
*
*
* There are two important notes concerning usage of matrices.
*
* First, the matrix indexes in all methods ({@link #index(long...) index},
* {@link #dim(int) dim(n)}, dim
argument in {@link MemoryModel#newMatrix(Class, Class, long...)
* MemoryModel.newMatrix}, etc.) are ordered from the lowest index to the highest.
* Please compare: for numeric matrix m
, m.array().getDouble(m.index(15,10))
* returns the element #15
of the row #10
. However,
* for usual 2-dimensional Java array,
* declared as "double[][] a
", the same element is accessed as
* a[10][15]
!
*
* Second, the number of indexes in the {@link #index(long...) index} method
* may differ from the number of dimensions ({@link #dimCount()}).
* In any case, the returned position in calculated by the formula listed above
* (in-1dn-2...d1d0 + ... +
* i2d1d0 +
* i1d0 + i0),
* where i0, i2, ..., in-1
* are the coordinates passed to the method, and dk is the dimension #k
* or 1 if k>={@link #dimCount()}
.
* In other words, it is supposed that all dimensions "after" the actual number of dimensions
* are always equal to 1. For example, the one-dimensional matrix with L
elements
* can be interpreted as 2-dimensional Lx1
matrix,
* or 3-dimensional Lx1x1
one, etc.
*
* The matrix object is immutable, that means that there are no ways to change
* any dimension or the reference to the built-in AlgART array.
* But the matrix elements can be modified, if the AlgART array is not
* {@link Array#asImmutable() immutable}.
* So, the matrix object is thread-safe or thread-compatible
* in the same situations as the built-in AlgART array: see comments to {@link Array} interface.
*
* The generic argument T
specifies the type of the built-in AlgART array.
* Any array type can be declared here, but the contract of this interface
* requires that the array must be {@link UpdatableArray#asUnresizable() unresizable}.
* So, there are no ways to create a matrix with {@link MutableArray} (or its subinterface)
* as the type argument, alike Matrix<MutableByteArray>
:
* all creation methods throw IllegalArgumentException
in this case.
*
* @param the type of the built-in AlgART array.
* @author Daniel Alievsky
* @see Array
* @see UpdatableArray
* @see MutableArray
*/
public interface Matrix extends Cloneable {
/**
* Continuation mode for submatrices, created by
* {@link Matrix#subMatrix(long[], long[], ContinuationMode continuationMode)},
* {@link Matrix#subMatr(long[], long[], ContinuationMode continuationMode)} and similar methods.
* The continuation mode is passed to those methods as the last argument and specifies,
* what will be the values of elements of the returned submatrix, which lie outside the original matrix.
* (This argument is not important if all submatrix elements belong to the original matrix,
* i.e. if the returned matrix is a true sub-matrix of the original one.)
*
* The following continuation modes are possible:
*
*
* - {@link #NONE}: continuation is not allowed;
* - {@link #CYCLIC}: cyclic repetition of the original matrix along all coordinates;
* - {@link #PSEUDO_CYCLIC}: pseudo-cyclic (toroidal) repetition of the original matrix,
* corresponding to the cyclic repetition of its {@link Matrix#array() built-in array};
* most of algorithms of image processing work in accordance with this model;
* - {@link #MIRROR_CYCLIC}: improved version of {@link #CYCLIC} model, where the original matrix
* is repeated with "mirror reflecting"; this mode provides the best smoothness of continuation;
* - {@link #getConstantMode(Object) constant continuation}: the space outside the original matrix
* is considered to be filled by some constant value.
*
*
* See comments to these modes for more details.
*
* Note: {@link #CYCLIC}, {@link #PSEUDO_CYCLIC}
* and {@link #MIRROR_CYCLIC} modes are not applicable for matrices with zero dimensions:
* if some matrix dimension {@link Matrix#dim(int) dim(k)}==0
, then the corresponding
* coordinate range of a submatrix must be 0..0
, as for {@link #NONE} continuation mode.
* See more details in comments to {@link Matrix#subMatrix(long[], long[], ContinuationMode)} method.
*
*
This class is immutable and thread-safe:
* there are no ways to modify settings of the created instance.
* Moreover, the constants {@link #NONE}, {@link #CYCLIC}, {@link #PSEUDO_CYCLIC}, {@link #MIRROR_CYCLIC},
* {@link #NULL_CONSTANT}, {@link #ZERO_CONSTANT}, {@link #NAN_CONSTANT},
* as well as constants in standard Java enumerations, are unique instances, which cannot be equal to any other
* instance of this class. So, you can use ==
Java operator to compare objects with these constants,
* instead of calling {@link #equals(Object)} method of this class.
*/
class ContinuationMode {
/**
* Simplest continuation mode: any continuation outside the source matrix is disabled.
*
* In this mode, the element of the returned submatrix with coordinates
* i0,i1,...,in-1
* always corresponds to the element of the source matrix m
* with the coordinates
* p0+i0,p1+i1,
* ..., pn-1+in-1
,
* where p0,p1,...,pn-1
* are the low endpoints of all coordinates in the submatrix,
* passed as the first argument of {@link Matrix#subMatrix(long[], long[], ContinuationMode)}
* or {@link Matrix#subMatr(long[], long[], ContinuationMode)} method.
* An attempt to read this element of the submatrix returns the corresponding element
* of the source matrix m
,
* and an attempt to write into this element of the submatrix modifies the corresponding element
* of the source matrix m
.
*
*
In a case of this mode, {@link Matrix#subMatrix(long[], long[], ContinuationMode continuationMode)}
* method is strictly equivalent to more simple {@link Matrix#subMatrix(long[], long[])}, and
* {@link Matrix#subMatr(long[], long[], ContinuationMode continuationMode)}
* is strictly equivalent to more simple {@link Matrix#subMatr(long[], long[])}.
* In other words, all submatrix elements must lie inside the original matrix,
* i.e. the returned matrix must be a true sub-matrix of the original one.
* An attempt to create a submatrix with this continuation mode,
* which does not lie fully inside the original matrix, leads to IndexOutOfBoundsException
.
*/
public static final ContinuationMode NONE = new ContinuationMode("not-continued mode");
/**
* The cyclic (or true-cyclic) continuation mode.
*
*
In this mode, the element of the returned submatrix with coordinates
* i0,i1,...,in-1
* corresponds to the element of the built-in array
* m.{@link Matrix#array() array()}
of the source matrix m
* with the index m.{@link Matrix#cyclicIndex(long...)
* cyclicIndex}(p0+i0,p1+i1,
* ..., pn-1+in-1)
,
* where p0,p1,...,pn-1
* are the low endpoints of all coordinates in the submatrix,
* passed as the first argument of {@link Matrix#subMatrix(long[], long[], ContinuationMode)}
* or {@link Matrix#subMatr(long[], long[], ContinuationMode)} method.
* An attempt to read this element of the submatrix returns the corresponding element
* of the source matrix m
,
* and an attempt to write into this element of the submatrix modifies the corresponding element
* of the source matrix m
.
*
*
In other words, in this mode you can consider that the resulting matrix
* is a submatrix of an infinite "matrix", which is come out from the original matrix
* by infinite periodical repeating along all coordinate axes.
*/
public static final ContinuationMode CYCLIC = new ContinuationMode(
"cyclically-continued mode");
/**
* The pseudo-cyclic (or toroidal) continuation mode.
*
*
In this mode, the element of the returned submatrix with coordinates
* i0,i1,...,in-1
* corresponds to the element of the built-in array
* m.{@link Matrix#array() array()}
of the source matrix m
* with the index m.{@link Matrix#pseudoCyclicIndex(long...)
* pseudoCyclicIndex}(p0+i0,p1+i1,
* ..., pn-1+in-1)
,
* where p0,p1,...,pn-1
* are the low endpoints of all coordinates in the submatrix,
* passed as the first argument of {@link Matrix#subMatrix(long[], long[], ContinuationMode)}
* or {@link Matrix#subMatr(long[], long[], ContinuationMode)} method.
* An attempt to read this element of the submatrix returns the corresponding element
* of the source matrix m
,
* and an attempt to write into this element of the submatrix modifies the corresponding element
* of the source matrix m
.
*
*
In other words, in this mode you can consider that the resulting matrix
* is a submatrix of an infinite "matrix", which is come out from the original matrix
* by infinite periodical repeating its {@link Matrix#array() built-in array}.
* It is the most natural mode for many image processing algorithms,
* which work directly with the built-in array instead of working with coordinates of matrix elements.
*/
public static final ContinuationMode PSEUDO_CYCLIC = new ContinuationMode(
"pseudo-cyclically-continued mode");
/**
* The mirror-cyclic continuation mode.
*
*
In this mode, the element of the returned submatrix with coordinates
* i0,i1,...,in-1
* corresponds to the element of the built-in array
* m.{@link Matrix#array() array()}
of the source matrix m
* with the index m.{@link Matrix#mirrorCyclicIndex(long...)
* mirrorCyclicIndex}(p0+i0,p1+i1,
* ..., pn-1+in-1)
,
* where p0,p1,...,pn-1
* are the low endpoints of all coordinates in the submatrix,
* passed as the first argument of {@link Matrix#subMatrix(long[], long[], ContinuationMode)}
* or {@link Matrix#subMatr(long[], long[], ContinuationMode)} method.
* An attempt to read this element of the submatrix returns the corresponding element
* of the source matrix m
,
* and an attempt to write into this element of the submatrix modifies the corresponding element
* of the source matrix m
.
*
*
In other words, in this mode you can consider that the resulting matrix
* is a submatrix of an infinite "matrix", which is come out from the original matrix
* by infinite periodical repeating along all coordinate axes, if, while every "odd" repeating,
* the matrix is symmetrically reflected along the corresponding coordinate.
* In other words, it's possible to say that the matrix is infinitely reflected in each its bound as
* in a mirror. Usually this mode provides the best smoothness of continuation of the matrix.
*/
public static final ContinuationMode MIRROR_CYCLIC = new ContinuationMode(
"mirroring-cyclically-continued mode");
/**
* The special case of constant continuation mode, corresponding to continuing by {@code null}
* constant. Strictly equivalent to {@link #getConstantMode(Object) getConstantMode(null)}
* (such a call always returns the reference to this constant).
*
*
Note: unlike {@link #ZERO_CONSTANT}, this mode can be used with any element type of the original matrix,
* including non-primitive objects. For matrices with primitive element type, this mode is equivalent
* to {@link #ZERO_CONSTANT}.
*/
public static final ContinuationMode NULL_CONSTANT = new ConstantImpl(null);
/**
* The special popular case of constant continuation mode, corresponding to continuing by 0.0d
* numeric constant. Strictly equivalent to
* {@link #getConstantMode(Object) getConstantMode(new Double(0.0d))}
* (such a call always returns the reference to this constant).
*
*
Note: unlike {@link #NULL_CONSTANT}, this mode can be used only with matrices, containing elements of
* some primitive type, i.e. with {@link Matrix}<? extends {@link PArray}>
.
*/
public static final ContinuationMode ZERO_CONSTANT = new ConstantImpl(0.0d);
/**
* The special popular case of constant continuation mode, corresponding to continuing by
* Double.NaN
numeric constant. Strictly equivalent to
* {@link #getConstantMode(Object) getConstantMode(new Double(Double.NaN))}
* (such a call always returns the reference to this constant).
*
*
Note: unlike {@link #NULL_CONSTANT}, this mode can be used only with matrices, containing elements of
* some primitive type, i.e. with {@link Matrix}<? extends {@link PArray}>
.
*/
public static final ContinuationMode NAN_CONSTANT = new ConstantImpl(Double.NaN);
/**
* Creates an instance of this class for constant continuation mode.
*
*
In this mode, the element of the returned submatrix with coordinates
* i0,i1,...,in-1
* corresponds to the element of the source matrix m
* with the coordinates
* p0+i0,p1+i1,
* ..., pn-1+in-1
* (where p0,p1,...,pn-1
* are the low endpoints of all coordinates in the submatrix,
* passed as the first argument of {@link Matrix#subMatrix(long[], long[], ContinuationMode)}
* or {@link Matrix#subMatr(long[], long[], ContinuationMode)} method) —
* if this element {@link Matrix#inside(long...) lies inside} the source matrix.
* In this case, an attempt to read this element of the submatrix returns the corresponding element
* of the source matrix m
,
* and an attempt to write into this element of the submatrix modifies the corresponding element
* of the source matrix m
.
* In another case (if this element lies outside the source matrix),
* the element is considered to be equal continuationConstant
(an argument of this method):
* an attempt to read it returns this constant, and
* an attempt to write into this element is just ignored.
*
*
In other words, in this mode, you can consider that the resulting matrix
* is a submatrix of an infinite "matrix", which is come out from the original matrix
* by infinite appending it along all coordinates with the specified continuation constant.
*
*
The argument continuationConstant
of this method is automatically cast to the type of
* elements of the source matrix m
according the following rules.
*
*
For non-primitive element types, the continuationConstant
argument
* must be some instance of the class m.{@link #elementType()}
,
* or its superclass, or {@code null}.
* So, the type cast is trivial here.
*
*
For primitive element types, continuationConstant
can be {@code null} or any
* wrapper for primitive types: Boolean
, Character
,
* Byte
, Short
,
* Integer
, Long
, Float
, Double
. In this case,
* the following casting rules are used while reading elements (I remind that attempts to write
* outside the original matrix are ignored),
* depending on the primitive type m.{@link #elementType()}
:
*
*
* - {@code null} is converted to
false
for bit elements or to zero (0
,
* (char)0
, 0.0
) for all other element types
* (so, it is the only universal continuation constant, which can be used with any element type:
* see {@link #NULL_CONSTANT});
*
* - if the wrapper type corresponds to the element primitive type, the trivial default conversion
* is used; in all other cases:
*
*
Boolean
value v
is converted to v?1:0
for numeric element types
* and to v?(char)1:(char)0
for char
element type;
*
* Character
value v
is converted to (byte)v
,
* (short)v
, (int)v
, (long)v
,
* (float)v
, (double)v
* for corresponding numeric element types
* and to v!=0
for boolean
element type;
*
* Byte
value v
is converted to (char)(v&0xFF)
,
* (short)(v&0xFF)
, (int)(v&0xFF)
, (long)(v&0xFF)
,
* (float)(v&0xFF)
, (double)(v&0xFF)
* for corresponding numeric or character element types
* and to v!=0
for boolean
element type;
*
* Short
value v
is converted to (char)v
,
* (byte)v
, (int)(v&0xFFFF)
, (long)(v&0xFFFF)
,
* (float)(v&0xFFFF)
, (double)(v&0xFFFF)
* for corresponding numeric or character element types
* and to v!=0
for boolean
element type;
*
* Integer
, Long
, Float
or Double
value v
* is converted to (char)v
,
* (byte)v
, (short)v
, (int)v
, (long)v
,
* (float)v
, (double)
v
* for corresponding numeric or character element types
* and to v!=0
for boolean
element type.
*
*
* @param continuationConstant the value returned while reading elements, lying outside this matrix.
* @return new continuation mode with the specified continuation constant.
*/
public static ContinuationMode getConstantMode(Object continuationConstant) {
if (continuationConstant == null) {
return NULL_CONSTANT;
}
if (ZERO_CONSTANT.continuationConstant().equals(continuationConstant)) {
return ZERO_CONSTANT;
}
if (NAN_CONSTANT.continuationConstant().equals(continuationConstant)) {
return NAN_CONSTANT;
}
return new ConstantImpl(continuationConstant);
}
private final String description;
private ContinuationMode(String description) {
assert description != null;
this.description = description;
}
/**
* Returns true
if and only if this instance is a constant continuation mode,
* i.e. was created by {@link #getConstantMode(Object)} method, or it is one
* of the predefined constants {@link #ZERO_CONSTANT} and {@link #NULL_CONSTANT}.
*
* @return whether it is a constant continuation mode.
*/
public boolean isConstant() {
return false;
}
/**
* Returns true
if and only if {@link #isConstant()} returns true and
* the result of {@link #continuationConstant()} is {@code null} or is an instance of
* some wrapper for primitive types: Boolean
, Character
,
* Byte
, Short
,
* Integer
, Long
, Float
or Double
.
*
* This method indicates, whether this mode can be used for constant continuation of a matrix
* with primitive type of elements. But note that such a mode can also be used for continuation of
* a matrix, consisting of non-primitive elements, belonging to the corresponding wrapper type
* or its superclass like Number
or Object
.
*
* @return whether it is a constant continuation mode, where the continuation constant is {@code null}
* or some Java wrapper object for a primitive type.
*/
public boolean isPrimitiveTypeOrNullConstant() {
return false;
}
/**
* Returns the continuation constant, used in this mode, if it is a
* {@link #isConstant() constant continuation mode},
* or throws {@link NonConstantMatrixContinuationModeException},
* if it is not a constant continuation mode.
*
*
If this instance was created by {@link #getConstantMode(Object)} method,
* this method returns exactly the same reference to an object, which was passed
* to that method as continuationConstant
argument.
* For {@link #NULL_CONSTANT}, this method returns {@code null}.
* For {@link #ZERO_CONSTANT}, this method returns Double.valueOf(0.0d)
.
* For {@link #NAN_CONSTANT}, this method returns Double.valueOf(Double.NaN)
.
*
* @return the continuation constant, used in this mode,
* if it is a {@link #isConstant() constant continuation mode},
* @throws NonConstantMatrixContinuationModeException if this mode is not a constant continuation mode.
* @see #isConstant()
*/
public Object continuationConstant() {
throw new NonConstantMatrixContinuationModeException(this + " has no continuation constant");
}
/**
* Returns a brief string description of this object.
*
*
The result of this method may depend on implementation.
*
* @return a brief string description of this object.
*/
@Override
public String toString() {
return description;
}
/**
* Returns the hash code of this object.
*
* @return the hash code of this object.
*/
@Override
public int hashCode() {
Object constant = isConstant() ? continuationConstant() : null;
return description.hashCode() ^ (constant != null ? constant.hashCode() : 157);
}
/**
* Indicates whether some continuation mode is equal to this instance.
*
*
If the argument is {@code null} or not an instance of this class,
* this method returns false
.
*
*
If this instance is a {@link #isConstant() constant continuation mode},
* this method returns true
if and only if the argument is also a constant continuation mode
* and either both continuation constants, returned by {@link #continuationConstant()} method,
* are {@code null}, or they are equal objects in terms of standard equals
method
* (i.e. equal
method of the {@link #continuationConstant()} object returns true
* for ((ContinuationMode)o).{@link #continuationConstant()}
).
*
*
If this instance is not a constant continuation mode, this method returns true
* if and only if this instance and o
argument are the same reference (this==o
).
* It is correct, because all only possible non-constant instances of this class are represented
* by static constants of this class, as well as in standard enumerations.
*
* @param o the object to be compared for equality with this instance.
* @return true
if the specified object is a continuation mode equal to this one.
*/
@Override
public boolean equals(Object o) {
if (!isConstant() || this == o) {
return this == o;
}
if (!(o instanceof ContinuationMode && ((ContinuationMode) o).isConstant())) {
return false;
}
Object constant = continuationConstant();
return constant == null ? ((ContinuationMode) o).continuationConstant() == null :
constant.equals(((ContinuationMode) o).continuationConstant());
}
private static class ConstantImpl extends ContinuationMode {
private final Object continuationConstant;
private final boolean primitiveTypeOrNullConstant;
private ConstantImpl(Object continuationConstant) {
super("constantly-continued (by " + continuationConstant + ") mode");
this.continuationConstant = continuationConstant;
this.primitiveTypeOrNullConstant = continuationConstant == null
|| continuationConstant instanceof Boolean
|| continuationConstant instanceof Character
|| continuationConstant instanceof Byte
|| continuationConstant instanceof Short
|| continuationConstant instanceof Integer
|| continuationConstant instanceof Long
|| continuationConstant instanceof Float
|| continuationConstant instanceof Double;
}
@Override
public boolean isConstant() {
return true;
}
@Override
public Object continuationConstant() {
return continuationConstant;
}
@Override
public boolean isPrimitiveTypeOrNullConstant() {
return primitiveTypeOrNullConstant;
}
}
}
/**
* Maximal number of dimensions for some complex algorithms or service classes: {@value}.
* Most modules process matrices with any number of dimensions, but there are some cases
* when an algorithm can work only with 2-dimensional, 3-dimensional or n-dimensional matrices with
* n<={@link #MAX_DIM_COUNT_FOR_SOME_ALGORITHMS}
.
* In this package and all known subpackages of net.algart
package,
* the following classes require that the number of dimensions must not be greater
* than {@link #MAX_DIM_COUNT_FOR_SOME_ALGORITHMS}:
*
* net.algart.matrices.scanning.ConnectedObjectScanner
;
* - {@link MatrixInfo}.
*
*
* Note: the value of this constant ({@value}) is the maximal n so that
* 3n<32768=215 (39=19683).
* It can be useful while storing indexes of elements of little 3x3x3x... submatrix (aperture):
* signed short
type is enough in this case.
*/
int MAX_DIM_COUNT_FOR_SOME_ALGORITHMS = 9;
/**
* Returns a reference to the built-in AlgART array.
*
*
There is a guarantee that this method works very quickly
* (usually it just returns a value of some private field).
*
* @return a reference to the built-in AlgART array.
*/
T array();
/**
* Returns the type of matrix elements.
* Equivalent to {@link #array()}.{@link Array#elementType() elementType()}
.
*
* @return the type of the matrix elements.
*/
Class> elementType();
/**
* Equivalent to {@link #array()}.{@link Array#toJavaArray() toJavaArray()}
.
*
* @return Java array containing all the elements in this matrix.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toByte()
* @see #toChar()
* @see #toShort()
* @see #toInt()
* @see #toLong()
* @see #toFloat()
* @see #toDouble()
* @see #ja()
* @see Array#toJavaArray()
*/
Object toJavaArray();
/**
* Equivalent to {@link #array()}.{@link Array#ja() ja()}
.
*
* @return Java array, equivalent to {@link #array()}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #jaByte()
* @see #jaChar()
* @see #jaShort()
* @see #jaInt()
* @see #jaLong()
* @see #jaFloat()
* @see #jaDouble()
* @see #toJavaArray()
* @see Array#ja()
*/
Object ja();
/*Repeat() byte ==> char,,short,,int,,long,,float,,double;;
Byte ==> Char,,Short,,Int,,Long,,Float,,Double */
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toByte() toByte()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to byte
type.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @see #toByte(byte[])
* @see #jaByte()
* @see #toJavaArray()
* @see PArray#toByte()
*/
default byte[] toByte() {
return toByte(null);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toByte(byte[]) toByte(result)}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @param result the result byte[]
array; can be {@code null},
* then it will be created automatically.
* @return a reference to result
argument or (when result==null
) a newly created array:
* Java array containing all the elements in this matrix,
* cast to byte
type according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @throws IndexOutOfBoundsException if the result
argument is not {@code null}, but its length
* is too small: less than {@link Matrix#size() matrix.size()}.
* @see #toByte()
* @see #jaByte()
* @see #toJavaArray()
* @see PArray#toByte(byte[])
*/
default byte[] toByte(byte[] result) {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using toByte(): " + this);
}
return a.toByte(result);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#jaByte() jaByte()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to byte
type
* according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toByte()
* @see #toByte(byte[])
* @see #ja
* @see PArray#jaByte()
*/
default byte[] jaByte() {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using jaByte(): " + this);
}
return a.jaByte();
}
/*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toChar() toChar()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to char
type.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @see #toChar(char[])
* @see #jaChar()
* @see #toJavaArray()
* @see PArray#toChar()
*/
default char[] toChar() {
return toChar(null);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toChar(char[]) toChar(result)}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @param result the result char[]
array; can be {@code null},
* then it will be created automatically.
* @return a reference to result
argument or (when result==null
) a newly created array:
* Java array containing all the elements in this matrix,
* cast to char
type according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @throws IndexOutOfBoundsException if the result
argument is not {@code null}, but its length
* is too small: less than {@link Matrix#size() matrix.size()}.
* @see #toChar()
* @see #jaChar()
* @see #toJavaArray()
* @see PArray#toChar(char[])
*/
default char[] toChar(char[] result) {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using toChar(): " + this);
}
return a.toChar(result);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#jaChar() jaChar()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to char
type
* according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toChar()
* @see #toChar(char[])
* @see #ja
* @see PArray#jaChar()
*/
default char[] jaChar() {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using jaChar(): " + this);
}
return a.jaChar();
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toShort() toShort()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to short
type.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @see #toShort(short[])
* @see #jaShort()
* @see #toJavaArray()
* @see PArray#toShort()
*/
default short[] toShort() {
return toShort(null);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toShort(short[]) toShort(result)}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @param result the result short[]
array; can be {@code null},
* then it will be created automatically.
* @return a reference to result
argument or (when result==null
) a newly created array:
* Java array containing all the elements in this matrix,
* cast to short
type according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @throws IndexOutOfBoundsException if the result
argument is not {@code null}, but its length
* is too small: less than {@link Matrix#size() matrix.size()}.
* @see #toShort()
* @see #jaShort()
* @see #toJavaArray()
* @see PArray#toShort(short[])
*/
default short[] toShort(short[] result) {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using toShort(): " + this);
}
return a.toShort(result);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#jaShort() jaShort()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to short
type
* according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toShort()
* @see #toShort(short[])
* @see #ja
* @see PArray#jaShort()
*/
default short[] jaShort() {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using jaShort(): " + this);
}
return a.jaShort();
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toInt() toInt()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to int
type.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @see #toInt(int[])
* @see #jaInt()
* @see #toJavaArray()
* @see PArray#toInt()
*/
default int[] toInt() {
return toInt(null);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toInt(int[]) toInt(result)}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @param result the result int[]
array; can be {@code null},
* then it will be created automatically.
* @return a reference to result
argument or (when result==null
) a newly created array:
* Java array containing all the elements in this matrix,
* cast to int
type according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @throws IndexOutOfBoundsException if the result
argument is not {@code null}, but its length
* is too small: less than {@link Matrix#size() matrix.size()}.
* @see #toInt()
* @see #jaInt()
* @see #toJavaArray()
* @see PArray#toInt(int[])
*/
default int[] toInt(int[] result) {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using toInt(): " + this);
}
return a.toInt(result);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#jaInt() jaInt()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to int
type
* according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toInt()
* @see #toInt(int[])
* @see #ja
* @see PArray#jaInt()
*/
default int[] jaInt() {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using jaInt(): " + this);
}
return a.jaInt();
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toLong() toLong()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to long
type.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @see #toLong(long[])
* @see #jaLong()
* @see #toJavaArray()
* @see PArray#toLong()
*/
default long[] toLong() {
return toLong(null);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toLong(long[]) toLong(result)}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @param result the result long[]
array; can be {@code null},
* then it will be created automatically.
* @return a reference to result
argument or (when result==null
) a newly created array:
* Java array containing all the elements in this matrix,
* cast to long
type according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @throws IndexOutOfBoundsException if the result
argument is not {@code null}, but its length
* is too small: less than {@link Matrix#size() matrix.size()}.
* @see #toLong()
* @see #jaLong()
* @see #toJavaArray()
* @see PArray#toLong(long[])
*/
default long[] toLong(long[] result) {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using toLong(): " + this);
}
return a.toLong(result);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#jaLong() jaLong()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to long
type
* according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toLong()
* @see #toLong(long[])
* @see #ja
* @see PArray#jaLong()
*/
default long[] jaLong() {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using jaLong(): " + this);
}
return a.jaLong();
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toFloat() toFloat()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to float
type.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @see #toFloat(float[])
* @see #jaFloat()
* @see #toJavaArray()
* @see PArray#toFloat()
*/
default float[] toFloat() {
return toFloat(null);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toFloat(float[]) toFloat(result)}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @param result the result float[]
array; can be {@code null},
* then it will be created automatically.
* @return a reference to result
argument or (when result==null
) a newly created array:
* Java array containing all the elements in this matrix,
* cast to float
type according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @throws IndexOutOfBoundsException if the result
argument is not {@code null}, but its length
* is too small: less than {@link Matrix#size() matrix.size()}.
* @see #toFloat()
* @see #jaFloat()
* @see #toJavaArray()
* @see PArray#toFloat(float[])
*/
default float[] toFloat(float[] result) {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using toFloat(): " + this);
}
return a.toFloat(result);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#jaFloat() jaFloat()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to float
type
* according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toFloat()
* @see #toFloat(float[])
* @see #ja
* @see PArray#jaFloat()
*/
default float[] jaFloat() {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using jaFloat(): " + this);
}
return a.jaFloat();
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toDouble() toDouble()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to double
type.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @see #toDouble(double[])
* @see #jaDouble()
* @see #toJavaArray()
* @see PArray#toDouble()
*/
default double[] toDouble() {
return toDouble(null);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#toDouble(double[]) toDouble(result)}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @param result the result double[]
array; can be {@code null},
* then it will be created automatically.
* @return a reference to result
argument or (when result==null
) a newly created array:
* Java array containing all the elements in this matrix,
* cast to double
type according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the matrix size is greater than Integer.MAX_VALUE
.
* @throws IndexOutOfBoundsException if the result
argument is not {@code null}, but its length
* is too small: less than {@link Matrix#size() matrix.size()}.
* @see #toDouble()
* @see #jaDouble()
* @see #toJavaArray()
* @see PArray#toDouble(double[])
*/
default double[] toDouble(double[] result) {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using toDouble(): " + this);
}
return a.toDouble(result);
}
/**
* Equivalent to (PArray) {@link #array()}.{@link PArray#jaDouble() jaDouble()}
.
* However, if the built-in AlgART array is not {@link PArray}, in other words,
* if this matrix contains objects (non-primitive elements), this method
* throws {@link UnsupportedOperationException} instead of {@link ClassCastException}.
*
* @return Java array containing all the elements in this matrix, cast to double
type
* according to AlgART rules.
* @throws UnsupportedOperationException if {@link #array()} is not {@link PArray}.
* @throws TooLargeArrayException if the array length is greater than Integer.MAX_VALUE
.
* @see #toDouble()
* @see #toDouble(double[])
* @see #ja
* @see PArray#jaDouble()
*/
default double[] jaDouble() {
if (!(array() instanceof PArray a)) {
throw new UnsupportedOperationException("Matrix, containing non-primitive (Object) elements, " +
"cannot be accessed using jaDouble(): " + this);
}
return a.jaDouble();
}
/*Repeat.AutoGeneratedEnd*/
/**
* Returns the total number of matrix elements.
* Equivalent to {@link #array()}.{@link Array#length() length()}
.
*
* @return the total number of matrix elements.
*/
default long size() {
return array().length();
}
/**
* Returns the total number of matrix elements as 32-bit int
value.
* Equivalent to {@link #array()}.{@link Array#length32() length32()}
.
*
* @return the total number of matrix elements, if it is less than 231.
* @throws TooLargeArrayException if the total number of matrix elements is greater than
* Integer.MAX_VALUE
=231−1.
*/
default int size32() {
return array().length32();
}
/**
* Equivalent to the call {@link #size() size}() == 0
.
*
* @return true
if the matrix is empty, i.e. at least one its dimensions is zero.
*/
default boolean isEmpty() {
return array().isEmpty();
}
/**
* Returns {@link #array()}.{@link Array#type() type()}
.
*
* @return the canonical type of AlgART array of the same kind as the built-in one.
* @throws NullPointerException if the passed argument is {@code null}.
*/
Class extends Array> type();
/**
* Returns {@link #array()}.{@link Array#updatableType() updatableType()}
.
*
* @return the canonical updatable type of AlgART array of the same kind as the built-in one.
* @throws NullPointerException if the passed argument is {@code null}.
*/
Class extends UpdatableArray> updatableType();
/**
* Returns {@link #array()}.{@link Array#type() type()}
,
* if it is a subtype of (or same type as) the passed arraySupertype
,
* or throws ClassCastException
in another case.
* (If the passed argument is a class of {@link UpdatableArray} or some its
* subinterfaces or subclasses, IllegalArgumentException
is thrown instead:
* updatable array classes cannot be specified in this method.)
*
* @param the generic type of AlgART array.
* @param arraySupertype the required supertype of the built-in AlgART array.
* @return the canonical type of AlgART array of the same kind as the built-in one.
* @throws NullPointerException if the passed argument is {@code null}.
* @throws IllegalArgumentException if the passed argument is a class of {@link UpdatableArray} or some its
* subinterfaces or subclasses (updatable classes cannot be supertypes of
* for {@link Array#type() Array.type()}).
* @throws ClassCastException if arraySupertype
does not allow storing
* the immutable version of the built-in AlgART array.
*/
Class extends U> type(Class arraySupertype);
/**
* Returns {@link #array()}.{@link Array#updatableType() updatableType()}
,
* if it is a subtype of (or same type as) the passed arraySupertype
,
* or throws ClassCastException
in another case.
*
* @param the generic type of AlgART array.
* @param arraySupertype the required supertype of the built-in AlgART array.
* @return the canonical updatable type of AlgART array of the same kind as the built-in one.
* @throws NullPointerException if the passed argument is {@code null}.
* @throws ClassCastException if arraySupertype
does not allow storing
* the built-in AlgART array.
*/
Class extends U> updatableType(Class arraySupertype);
/**
* Returns true
if and only if the {@link #elementType() element type} is primitive:
* {@link #array()} instanceof {@link PArray}
.
*
* @return whether the type of matrix element is boolean, char, byte, short, int, long, float or double.
*/
boolean isPrimitive();
/**
* Returns true
if and only if the {@link #elementType() element type} is float
* or double
:
* {@link #array()} instanceof {@link PFloatingArray}
.
*
* @return whether the type of matrix element is float or double.
*/
boolean isFloatingPoint();
/**
* Returns true
if and only if the {@link #elementType() element type} is fixed-point:
* {@link #array()} instanceof {@link PFixedArray}
.
*
* @return whether the type of matrix element is byte, short, int, long, char or boolean.
*/
boolean isFixedPoint();
/**
* Returns true
if and only if the {@link #elementType() element type} is boolean.class
,
* short.class
, byte.class
or short.class
.
*
*
Equivalent to {@link Arrays#isUnsignedElementType(Class)
* Arrays.isUnsignedElementType}(thisMatrix.{@link #elementType() elementType()}).
*
* @return whether the element type of this matrix should be interpreted as unsigned primitive type.
*/
boolean isUnsigned();
/**
* Returns the number of in bits, required for each element of this matrix, if they are
* {@link #isPrimitive() primitive}; in another case returns −1.
* Equivalent to {@link Arrays#bitsPerElement(Class)
* Arrays.bitsPerElement}(thisMatrix.{@link #elementType() elementType()}).
*
* @return the size of each element in bits or −1 if for non-primitive elements.
*/
long bitsPerElement();
/**
* Returns the maximal possible value, that can stored in elements of this matrix,
* if they are fixed-point elements, or the argument for floating-point elements,
* or Double.NaN
if elements are not primitive.
*
*
Equivalent to
* thisMatrix.{@link #isPrimitive() isPrimitive()} ?
* ((PArray) thisMatrix.array()).{@link PArray#maxPossibleValue(double)
* maxPossibleValue(valueForFloatingPoint)} :
* Double.NaN;
*
*
* @param valueForFloatingPoint some "default" value returned for floating-point element type.
* @return {@link #array()}.{@link PArray#maxPossibleValue maxPossibleValue()} for primitive element types,
* or Double.NaN
for non-primitive element types.
*/
double maxPossibleValue(double valueForFloatingPoint);
/**
* Returns the maximal possible value, that can stored in elements of this matrix,
* if they are fixed-point elements, or 1.0
for floating-point elements,
* or Double.NaN
if elements are not primitive.
*
* Equivalent to {@link #maxPossibleValue(double) maxPossibleValue(1.0)}.
* It is a good default for most application.
*
* @return maximal possible value for primitive element types (1.0 for float/double),
* or Double.NaN
for non-primitive element types.
*/
double maxPossibleValue();
/**
* Returns an array containing all dimensions of this matrix.
* Returned array is equal to the dim
argument passed to methods that create new matrix instances.
*
*
The returned array is a clone of the internal dimension array, stored in this object.
* The returned array is never empty (its length cannot be zero).
* The elements of the returned array are never negative.
*
* @return an array containing all dimensions of this matrix.
*/
long[] dimensions();
/**
* Returns the number of dimensions of this matrix.
* This value is always positive (>=1).
* Equivalent to {@link #dimensions()}.length
, but works faster.
*
*
There is a guarantee that this method works very quickly
* (usually it just returns a value of some private field).
*
* @return the number of dimensions of this matrix.
*/
int dimCount();
/**
* Returns the dimension #n
of this matrix
* or 1
if n>={@link #dimCount()}
.
* Equivalent to n<{@link #dimCount()}?{@link #dimensions()}[n]:1
, but works faster.
*
*
There is a guarantee that this method works very quickly.
*
* @param n the index of dimension.
* @return the dimension #n
of this matrix or 1 if the index is too large.
* @throws IndexOutOfBoundsException if n<0
(but not if n
is too large).
* @see #dim32(int)
*/
long dim(int n);
/**
* Returns the same result as the method {@link #dim(int) dim(n)} as 32-bit int
value.
* If the dimension, returned by {@link #dim(int) dim(n)}, is greater than Integer.MAX_VALUE
,
* throws TooLargeArrayException
.
*
*
This method is convenient when you are sure that matrix sizes
* cannot exceed the limit 231−1.
*
* @param n the index of dimension.
* @return the dimension #n
of this matrix, if it is less than 231.
* @throws IndexOutOfBoundsException if n<0
(but not if n
is too large).
* @throws TooLargeArrayException if this matrix dimension is greater than
* Integer.MAX_VALUE
=231−1.
*/
default int dim32(int n) {
long result = dim(n);
if (result < 0) {
throw new AssertionError("Negative result " + result + " of dim() method");
}
if (result > Integer.MAX_VALUE) {
throw new TooLargeArrayException("Too large matrix dimension #" + n + " (" +
result + " >= 2^31): " + this);
}
return (int) result;
}
/**
* Equivalent to {@link #dim(int) dim}(0)
.
*
* @return the first matrix dimension.
*/
default long dimX() {
return dim(0);
}
/**
* Equivalent to {@link #dim32(int) dim32}(0)
.
*
* @return the first matrix dimension.
* @throws TooLargeArrayException if this matrix dimension is greater than
* Integer.MAX_VALUE
=231−1.
*/
default int dimX32() {
return dim32(0);
}
/**
* Equivalent to {@link #dim(int) dim}(1)
.
*
* @return the second matrix dimension (or 1 for 1-dimensional matrix).
*/
default long dimY() {
return dim(1);
}
/**
* Equivalent to {@link #dim32(int) dim32}(1)
.
*
* @return the second matrix dimension (or 1 for 1-dimensional matrix).
* @throws TooLargeArrayException if this matrix dimension is greater than
* Integer.MAX_VALUE
=231−1.
*/
default int dimY32() {
return dim32(1);
}
/**
* Equivalent to {@link #dim(int) dim}(2)
.
*
* @return the third matrix dimension (or 1 for 1-dimensional or 2-dimensional matrix).
*/
default long dimZ() {
return dim(2);
}
/**
* Equivalent to {@link #dim32(int) dim32}(2)
.
*
* @return the third matrix dimension (or 1 for 1-dimensional or 2-dimensional matrix).
* @throws TooLargeArrayException if this matrix dimension is greater than
* Integer.MAX_VALUE
=231−1.
*/
default int dimZ32() {
return dim32(2);
}
/**
* Indicates whether the other matrix has the same dimension array.
* In other words, returns true
if and only if
* both matrices have the same dimension count ({@link #dimCount()})
* and the corresponding dimensions ({@link #dim(int) dim(k)}) are equal.
*
* @param m the matrix to be compared for equal dimensions with this matrix.
* @return true
if the specified matrix has the same dimension array.
* @throws NullPointerException if the passed argument is {@code null}.
* @see #dimEquals(long...)
*/
boolean dimEquals(Matrix> m);
/**
* Indicates whether the passed dimensions are equal to the dimension array of this matrix.
* In other words, returns true
if and only if
* dimension.length=={@link #dimCount()}
* and the corresponding dimensions {@link #dim(int) dim(k)}==dimension[k]
for all k
.
*
* Note: this method does not check, whether all passed dimensions are correct (in particular, non-negative).
* If some elements of the passed array are incorrect, this method just returns false
.
* But it the passed array is {@code null}, this method throws NullPointerException
.
*
* @param dimensions the dimension array.
* @return true
if the specified dimensions are equal to the dimensions of this matrix.
* @throws NullPointerException if the passed argument is {@code null}.
* @see #dimEquals(Matrix)
*/
boolean dimEquals(long... dimensions);
/**
* Returns the linear index in the built-in AlgART array of the matrix element
* with specified coordinates.
*
*
More precisely,
* index(i0,i1,...,in-1)
* returns the following value:
*
*
* in-1dn-2...d1d0 + ... +
* i2d1d0 +
* i1d0 + i0,
*
*
* where dk={@link #dim(int) dim}(k)
.
* All passed indexes ik
must be in ranges 0..dk-1
.
*
*
All elements of coordinates
array are always used, regardless
* of the number of matrix dimensions.
* But the extra elements of coordinates
array must be zero,
* because dk=1
for k>={@link #dimCount()}
.
*
*
Good algorithms processing the matrix should use this method rarely:
* usually there are more optimal ways to calculate necessary linear index.
* For example, if you just need to calculate something for all matrix elements,
* the best way is the following:
*
*
* Array a = m.array();
* for (long disp = 0, n = a.length(); disp < n; disp++)
* // process the element #k of the array
*
*
* @param coordinates all coordinates.
* @return the linear index of the matrix element with specified coordinates.
* @throws NullPointerException if the passed array is {@code null}.
* @throws IllegalArgumentException if the passed array is empty (no coordinates are passed).
* @throws IndexOutOfBoundsException if some coordinate ik
is out of range
* 0..dk-1
.
* @see #uncheckedIndex(long...)
* @see #cyclicIndex(long...)
* @see #pseudoCyclicIndex(long...)
* @see #mirrorCyclicIndex(long...)
* @see #coordinates(long, long[])
* @see IPoint#toOneDimensional(long[], boolean)
*/
long index(long... coordinates);
/**
* The simplified version of the full {@link #index(long...) index} method for the case
* of 2-dimensional matrix.
*
* @param x the first coordinate.
* @param y the second coordinate.
* @return y * {@link #dimX()} + x
.
* @throws IndexOutOfBoundsException if x<0
, x>={@link #dimX()}
,
* y<0
or y>={@link #dimX()}
.
*/
long index(long x, long y);
/**
* The simplified version of the full {@link #index(long...) index} method for the case
* of 3-dimensional matrix.
*
* @param x the first coordinate.
* @param y the second coordinate.
* @param z the third coordinate.
* @return z * {@link #dimY()} * {@link #dimX()} + y * {@link #dimX()} + x
.
* @throws IndexOutOfBoundsException if x<0
, x>={@link #dimX()}
,
* y<0
, y>={@link #dimX()}
,
* z<0
or z>={@link #dimZ()}
.
*/
long index(long x, long y, long z);
/**
* Returns the coordinates in the matrix, corresponding to the given linear index in the built-in AlgART array.
* This method is reverse to {@link #index(long...)}: for any index,
* {@link #index(long...) index}({@link #coordinates(long, long[])
* coordinates}(index, null)) == index
.
*
* The result
argument can be {@code null} or some array,
* containing at least {@link #dimCount()}
* elements. If the first case, this method allocates new Java array long[{@link #dimCount()}]
* for storing coordinates and returns it.
* In the second case, this method stores the found coordinates in result
array and returns it.
* The returned coordinates are always in ranges
*
* 0 ≤ result[k] < {@link #dim(int) dim}(k)
*
* @param index the linear index in the built-in AlgART array.
* @param result the array where you want to store results; can be {@code null}.
* @return a reference to the result
argument, if it is not {@code null},
* else newly created Java array contains all calculated coordinates.
* @throws IllegalArgumentException if result!=null
,
* but result.length<{@link #dimCount()}
.
* @throws IndexOutOfBoundsException if index<0
or index>={@link #dim(int)
* dim}(0)*{@link #dim(int) dim}(1)*...={@link #array()}.{@link
* Array#length() length()}
.
*/
long[] coordinates(long index, long[] result);
/**
* An analog of {@link #index(long...)} method, that does not check,
* whether the passed coordinates are in the required ranges.
*
* More precisely,
* uncheckedIndex(i0,i1,...,in-1)
* always returns the following value:
*
*
* in-1dn-2...d1d0 + ... +
* i2d1d0 +
* i1d0 + i0,
*
*
* where dk={@link #dim(int) dim}(k)
.
*
*
All calculations are performed with long
type without any overflow checks.
* All elements of coordinates
array are always used, regardless of the number of matrix dimensions.
* Please remember that dk={@link #dim(int) dim}(k)=1
* for k>={@link #dimCount()}
* (extra elements of coordinates
array).
*
* @param coordinates all coordinates.
* @return the linear index of the matrix element with specified coordinates, without range checks.
* @throws NullPointerException if the passed array is {@code null}.
* @throws IllegalArgumentException if the passed array is empty (no coordinates are passed).
*/
long uncheckedIndex(long... coordinates);
/**
* An analog of {@link #index(long...)} method, that, before all calculations,
* replaces the passed coordinates with the positive remainders
* from division of them by the corresponding matrix dimensions.
*
*
More precisely, let i0,i1,...,in-1
* are the arguments of the method. Let
* dk={@link #dim(int) dim}(k)
and
*
* i'k = dk == 0 ? 0 :
* ik % dk >= 0 ?
* ik % dk :
* ik % dk + dk
*
*
* This method returns the following value:
*
*
* i'n-1dn-2...d1d0 + ... +
* i'2d1d0 +
* i'1d0 + i'0,
*
*
* In other words, the resulting index is "cyclical".
*
*
All elements of coordinates
array are always used,
* regardless of the number of matrix dimensions.
* (You can note that extra elements of coordinates
array are ignored in fact:
* the reminders ik%dk=ik%1 will be zero for them.)
*
* @param coordinates all coordinates.
* @return the cyclical linear index of the matrix element with specified coordinates,
* without range checks.
* @throws NullPointerException if the passed array is {@code null}.
* @throws IllegalArgumentException if the passed array is empty (no coordinates are passed).
* @see Matrix.ContinuationMode#CYCLIC
*/
long cyclicIndex(long... coordinates);
/**
* An analog of {@link #index(long...)} method, that does not check,
* whether the passed coordinates are in the required ranges,
* but replaces the resulting index with the positive remainder
* from division of it by the length of the built-in array.
*
*
More precisely, let i0,i1,...,in-1
* are the arguments of the method, and index
is the following value
* (as in {@link #index(long...)} method):
*
*
* index
= in-1dn-2...d1d0 + ... +
* i2d1d0 +
* i1d0 + i0,
*
*
* where dk={@link #dim(int) dim}(k)
.
* Here we do no require that the passed indexes ik
* are in ranges 0..dk-1
.
* Then, let len={@link #array()}.{@link Array#length()
* length()}=dn-1...d1d0
.
* The result of this method is the following:
*
*
* len == 0 ? 0 : index % len >= 0 ?
* index % len : index % len + len
*
*
* (It is in the 0..len-1
range always,
* excepting the degenerated case len==0
.)
* In other words, the resulting index is "pseudo-cyclical", as the resulting shift
* in {@link Matrices#asShifted(Matrix, long...)} method.
*
*
All elements of coordinates
array are always used,
* regardless of the number of matrix dimensions.
* (You can note that extra elements of coordinates
array are ignored in fact:
* they add k*len
summand, where k
is an integer.)
*
*
Note that all calculations are performed absolutely precisely, even in a case when
* the direct calculation according the formulas above leads to overflow (because some
* of the values in these formulas are out of Long.MIN_VALUE..Long.MAX_VALUE
range).
*
* @param coordinates all coordinates.
* @return the pseudo-cyclical linear index of the matrix element with specified coordinates,
* without range checks.
* @throws NullPointerException if the passed array is {@code null}.
* @throws IllegalArgumentException if the passed array is empty (no coordinates are passed).
* @see IPoint#toOneDimensional(long[], boolean)
* @see Matrix.ContinuationMode#PSEUDO_CYCLIC
*/
long pseudoCyclicIndex(long... coordinates);
/**
* An analog of {@link #index(long...)} method, that, before all calculations,
* replaces the passed coordinates with the positive remainders
* from division of them by the corresponding matrix dimensions
* or with complement of these remainders on the dimensions,
* as if the matrix would be reflected in each its bound as in a mirror.
*
*
More precisely, let i0,i1,...,in-1
* are the arguments of the method. Let
* dk={@link #dim(int) dim}(k)
,
*
* i'k = dk == 0 ? 0 :
* ik % dk >= 0 ?
* ik % dk :
* ik % dk + dk
*
* (as in {@link #cyclicIndex(long...)}) and
*
* i''k = dk == 0 ? 0 :
* ⌊ik / dk⌋ % 2 == 0 ?
* i'k :
* dk − 1 − i'k
*
* (here ⌊x⌋ means the integer part of x, i.e. Math.floor(x)
).
*
* This method returns the following value:
*
*
* i''n-1dn-2...d1d0 + ... +
* i''2d1d0 +
* i''1d0 + i''0,
*
*
* In other words, the resulting index is "mirroring-cyclical".
*
*
All elements of coordinates
array are always used, regardless of the number of matrix dimensions.
* (You can note that extra elements of coordinates
array are ignored in fact:
* the reminders ik%dk=ik%1 will be zero for them.)
*
* @param coordinates all coordinates.
* @return the mirror-cyclical linear index of the matrix element with specified coordinates,
* without range checks.
* @throws NullPointerException if the passed array is {@code null}.
* @throws IllegalArgumentException if the passed array is empty (no coordinates are passed).
* @see Matrix.ContinuationMode#MIRROR_CYCLIC
*/
long mirrorCyclicIndex(long... coordinates);
/**
* Returns true
if all specified coordinates ik
* are inside the ranges 0..dk-1
,
* where dk={@link #dim(int) dim}(k)
.
*
*
This method allows simply check that the arguments of
* the {@link #index(long...) index} method are correct and will not lead to
* IndexOutOfBoundsException
:
*
* if (matrix.inside(i1, i2, ...)) {
* long index = matrix.index(i1, i2, ...);
* // processing an element at this index
* } else {
* // special branch for positions outside the matrix
* }
*
*
* @param coordinates all coordinates.
* @return true
if all specified coordinates are inside the matrix.
* @throws NullPointerException if the passed array is {@code null}.
* @throws IllegalArgumentException if the passed array is empty (no coordinates are passed).
*/
boolean inside(long... coordinates);
/**
* The simplified version of the full {@link #inside(long...) inside} method for the case
* of 2-dimensional matrix.
*
* @param x the first coordinate.
* @param y the second coordinate.
* @return true
if all specified coordinates are inside the matrix.
*/
boolean inside(long x, long y);
/**
* The simplified version of the full {@link #inside(long...) inside} method for the case
* of 3-dimensional matrix.
*
* @param x the first coordinate.
* @param y the second coordinate.
* @param z the third coordinate.
* @return true
if all specified coordinates are inside the matrix.
*/
boolean inside(long x, long y, long z);
/**
* Returns the new matrix backed by the specified AlgART array with the same dimensions as this one.
* Equivalent to {@link Matrices#matrix(Array, long...)
* Matrices.matrix}(anotherArray, {@link #dimensions()})
.
*
* The array anotherArray
must be {@link Array#isUnresizable() unresizable},
* and its length must be equal to the length of the array built-in this matrix.
*
* @param the generic type of AlgART array.
* @param anotherArray some another AlgART array with the same length as {@link #array()}.
* @return new matrix instance.
* @throws NullPointerException if anotherArray
argument is {@code null}.
* @throws IllegalArgumentException if the passed array is resizable
* (for example, implements {@link MutableArray}).
* @throws SizeMismatchException if the product of all dimensions is not equal to the passed array length.
*/
Matrix matrix(U anotherArray);
/**
* Returns this matrix, cast to the specified generic array type,
* or throws ClassCastException
if the built-in AlgART array
* cannot be cast to the required type (because the array type is not its subclass).
* Works alike {@link #matrix(Array) matrix}((U)array)
, but returns
* the reference to this instance and is compiled without "unchecked cast" warning.
*
*
This method is useful when you need to cast the type of AlgART array,
* built in this matrix, to to its sub- or superinterface.
*
* @param the generic type of AlgART array.
* @param arrayClass the type of built-in array in the new matrix.
* @return new matrix with the same dimensions, based on the same array cast to the required type.
* @throws NullPointerException if the argument is {@code null}.
* @throws ClassCastException if the built-in AlgART array cannot be cast to the required type.
*/
Matrix cast(Class arrayClass);
/**
* Returns a view of the rectangular fragment of this matrix between from
,
* inclusive, and to
, exclusive.
*
*
More precisely, the returned matrix consists of all elements of this one with coordinates
* i0, i1, ..., in−1,
* n={@link #dimCount()}
,
* matching the following conditions:
* from[0] <= i0 < to[0],
* from[1] <= i1 < to[1],
* . . .
* from[n-1] <= in-1 < to[n-1]
*
*
* So, every dimension {@link #dim(int) dim(k)} in the returned matrix will be equal to to[k]-from[k]
.
* The following condition must be fulfilled for all k
:
* 0<=from[k]<=to[k]<=thisMatrix.{@link #dim(int) dim(k)}
.
* The {@link #elementType() element type} of the returned matrix is identical to the element type
* of this matrix.
*
*
This method is equivalent to the call
* {@link #subMatrix(long[], long[], ContinuationMode)
* subMatrix}(from,to,{@link Matrix.ContinuationMode#NONE})
.
*
*
The built-in AlgART array of the returned matrix is backed by the built-in array of this matrix,
* so — if this matrix is not {@link #isImmutable() immutable}
* — any changes of the elements in the returned matrix are reflected in this matrix, and vice versa.
* The returned matrix is {@link #isImmutable() immutable} if, and only if,
* the built-in array of this matrix does not implement {@link UpdatableArray}.
* The {@link Array#asTrustedImmutable()} method
* in the built-in array of the returned matrix is equivalent to {@link Array#asImmutable()},
* and {@link Array#asCopyOnNextWrite()} method just returns the full copy of the array.
*
* @param from low endpoints (inclusive) of all coordinates.
* @param to high endpoints (exclusive) of all coordinates.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if from
or to
argument is {@code null}.
* @throws IllegalArgumentException if from.length
or to.length
* is not equal to {@link #dimCount()}.
* @throws IndexOutOfBoundsException if, for some k
,
* from[k]<0 || to[k]>{@link #dim(int) dim(k)} ||
* from[k]>to[k]
.
* @see #subMatrix(long[], long[], ContinuationMode)
* @see #subMatrix(IRectangularArea)
* @see #subMatr(long[], long[], ContinuationMode)
* @see #subMatr(long[], long[])
* @see #isSubMatrix()
*/
Matrix subMatrix(long[] from, long[] to);
/**
* Equivalent to {@link #subMatrix(long[] from, long[] to)} method, where
* from.length=to.length=area.{@link IRectangularArea#coordCount() coordCount()}
,
* from[k]=area.{@link IRectangularArea#min(int) min}(k)
,
* to[k]=area.{@link IRectangularArea#max(int) max}(k)+1
.
*
* @param area rectangular area within this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if the argument is {@code null}.
* @throws IllegalArgumentException if area.{@link IRectangularArea#coordCount() coordCount()}
* is not equal to {@link #dimCount()}.
* @throws IndexOutOfBoundsException if, for some k
,
* min[k]<0 || max[k]>={@link #dim(int) dim(k)}
, where
* min=area.{@link IRectangularArea#min()
* min()}.{@link IPoint#coordinates() coordinates()}
and,
* max=area.{@link IRectangularArea#max()
* max()}.{@link IPoint#coordinates() coordinates()}
.
*/
Matrix subMatrix(IRectangularArea area);
/**
* Equivalent to {@link #subMatrix(long[], long[])
* subMatrix}(new long[]{fromX,fromY}, new long[]{toX,toY})
.
* Note that this matrix must be 2-dimensional
* (in another case IllegalArgumentException
will be thrown).
*
* @param fromX low endpoints (inclusive) of the first coordinate.
* @param fromY low endpoints (inclusive) of the second coordinate.
* @param toX high endpoints (exclusive) of the first coordinate.
* @param toY high endpoints (exclusive) of the second coordinate.
* @return a view of the specified rectangular fragment within this matrix.
* @throws IllegalArgumentException if {@link #dimCount()}!=2
.
* @throws IndexOutOfBoundsException in the same situations as in {@link #subMatrix(long[], long[])}.
*/
Matrix subMatrix(long fromX, long fromY, long toX, long toY);
/**
* Equivalent to {@link #subMatrix(long[], long[])
* subMatrix}(new long[]{fromX,fromY,fromZ}, new long[]{toX,toY,toZ})
.
* Note that this matrix must be 3-dimensional
* (in another case IllegalArgumentException
will be thrown).
*
* @param fromX low endpoints (inclusive) of the first coordinate.
* @param fromY low endpoints (inclusive) of the second coordinate.
* @param fromZ low endpoints (inclusive) of the third coordinate.
* @param toX high endpoints (exclusive) of the first coordinate.
* @param toY high endpoints (exclusive) of the second coordinate.
* @param toZ high endpoints (exclusive) of the third coordinate.
* @return a view of the specified rectangular fragment within this matrix.
* @throws IllegalArgumentException if {@link #dimCount()}!=3
.
* @throws IndexOutOfBoundsException in the same situations as in {@link #subMatrix(long[], long[])}.
*/
Matrix subMatrix(long fromX, long fromY, long fromZ, long toX, long toY, long toZ);
/**
* An extended analog of {@link #subMatrix(long[], long[])} method, allowing to get a rectangular fragment
* which is not fully inside this matrix.
*
* More precisely, unlike {@link #subMatrix(long[], long[])}, here
* the only requirement for the from
* and to
coordinate boundaries is from[k]<=to[k]
,
* but from[k]
may be negative and to[k]
may be greater than {@link #dim(int) dim(k)}.
* (And there is also a trivial obvious requirement
* to[k]-from[k]≤Long.MAX_VALUE
, i.e. that the dimensions of the result must
* be representable by long
type.)
*
*
The elements of the returned matrix, that do not correspond to any elements of this one,
* i.e. "lie outside" of this matrix, are considered to be equal to some values, according to
* some continuation model, described by continuationMode
argument.
* Such "outside" elements can correspond (according some rules) to actual elements of the source elements —
* then attempts to read them return the values of the corresponding source elements
* and attempts to write into them modify the corresponding source elements
* (it is so for {@link ContinuationMode#CYCLIC}, {@link ContinuationMode#PSEUDO_CYCLIC},
* {@link ContinuationMode#MIRROR_CYCLIC} modes),
* — or can be calculated "virtually" (according some rules) —
* then attempts to read them return the calculated values
* and attempts to modify them are ignored
* (it is so for the {@link ContinuationMode#getConstantMode(Object) constant continuation} mode).
* See {@link ContinuationMode} class for more details.
*
*
Important note: there are two cases, when requirements to the from
and to
* coordinate boundaries are stronger, than described above.
*
* - If
continuationMode=={@link ContinuationMode#NONE}
, this method is strictly
* equivalent to more simple {@link Matrix#subMatrix(long[], long[])} method,
* so all requirements are the same as for that method.
* - If
continuationMode
is {@link ContinuationMode#CYCLIC},
* {@link ContinuationMode#PSEUDO_CYCLIC} or {@link ContinuationMode#MIRROR_CYCLIC}
* (but it is not a constant continuation mode) and some dimension #k
* of this matrix is zero — {@link #dim(int) dim}(k)==0
—
* then both corresponding coordinate boundaries from[k]
and to[k]
* must be zero (as in {@link Matrix#subMatrix(long[], long[])} method).
*
*
* @param from low endpoints (inclusive) of all coordinates.
* @param to high endpoints (exclusive) of all coordinates.
* @param continuationMode the mode of continuation outside this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if from
, to
or continuationMode
* argument is {@code null}.
* @throws IllegalArgumentException if from.length
or to.length
* is not equal to {@link #dimCount()}.
* @throws IndexOutOfBoundsException for continuationMode=={@link ContinuationMode#NONE}
—
* see {@link Matrix#subMatrix(long[], long[])} method;
* for other cases — if, for some k
,
* from[k]>to[k]
or
* to[k]-from[k]>Long.MAX_VALUE
,
* or if (for some k
) {@link #dim(int) dim(k)}==0
and
* from[k]!=0 || to[k]!=0
,
* or if the product of all differences to[k]-from[k]
* (i.e. desired total size of the new matrix)
* is greater than Long.MAX_VALUE
.
* @throws ClassCastException if continuationMode
is {@link
* ContinuationMode#getConstantMode(Object) a constant mode},
* the {@link Matrix.ContinuationMode#continuationConstant()
* continuation constant} is not {@code null} and the class of this
* constant is illegal, i.e.
* cannot be cast to the necessary type according the rules, specified
* for the {@link
* ContinuationMode#getConstantMode(Object) constant continuation mode}.
* @see #subMatr(long[], long[], ContinuationMode)
* @see #subMatrix(long[], long[])
* @see #subMatr(long[], long[])
* @see #isSubMatrix()
*/
Matrix subMatrix(long[] from, long[] to, ContinuationMode continuationMode);
/**
* Equivalent to {@link #subMatrix(long[] from, long[] to, ContinuationMode continuationMode)} method, where
* from.length=to.length=area.{@link IRectangularArea#coordCount() coordCount()}
,
* from[k]=area.{@link IRectangularArea#min(int) min}(k)
,
* to[k]=area.{@link IRectangularArea#max(int) max}(k)+1
.
*
* @param area rectangular area within this matrix.
* @param continuationMode the value returned while reading elements, lying outside this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if area.{@link IRectangularArea#coordCount() coordCount()}
* is not equal to {@link #dimCount()}.
* @throws IndexOutOfBoundsException for continuationMode=={@link ContinuationMode#NONE}
—
* see {@link Matrix#subMatrix(long[], long[])} method; for other cases —
* if the product of all area.{@link IRectangularArea#sizes()}
* (i.e. desired total size of the new matrix)
* is greater than Long.MAX_VALUE
.
* @throws ClassCastException if continuationMode
is {@link
* ContinuationMode#getConstantMode(Object) a constant mode},
* the {@link Matrix.ContinuationMode#continuationConstant()
* continuation constant} is not {@code null} and the class of this
* constant is illegal, i.e.
* cannot be cast to the necessary type according the rules, specified
* for the {@link
* ContinuationMode#getConstantMode(Object) constant continuation mode}.
*/
Matrix subMatrix(IRectangularArea area, ContinuationMode continuationMode);
/**
* Equivalent to {@link #subMatrix(long[], long[], ContinuationMode)
* subMatrix}(new long[]{fromX,fromY}, new long[]{toX,toY}, continuationMode)
.
* Note that this matrix must be 2-dimensional
* (in another case IllegalArgumentException
will be thrown).
*
* @param fromX low endpoints (inclusive) of the first coordinate.
* @param fromY low endpoints (inclusive) of the second coordinate.
* @param toX high endpoints (exclusive) of the first coordinate.
* @param toY high endpoints (exclusive) of the second coordinate.
* @param continuationMode the value returned while reading elements, lying outside this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if continuationMode
argument is {@code null}.
* @throws IllegalArgumentException if {@link #dimCount()}!=2
.
* @throws IndexOutOfBoundsException for continuationMode=={@link ContinuationMode#NONE}
—
* see {@link Matrix#subMatrix(long[], long[])} method; for other cases —
* if fromX>toX
or toX-fromX>Long.MAX_VALUE
,
* or if fromY>toY
or toY-fromY>Long.MAX_VALUE
,
* or if the product (toX-fromX)*(toY-fromY)
* (i.e. desired total size of the new matrix)
* is greater than Long.MAX_VALUE
.
* @throws ClassCastException if continuationMode
is {@link
* ContinuationMode#getConstantMode(Object) a constant mode},
* the {@link Matrix.ContinuationMode#continuationConstant()
* continuation constant} is not {@code null} and the class of this
* constant is illegal, i.e.
* cannot be cast to the necessary type according the rules, specified
* for the {@link
* ContinuationMode#getConstantMode(Object) constant continuation mode}.
*/
Matrix subMatrix(long fromX, long fromY, long toX, long toY, ContinuationMode continuationMode);
/**
* Equivalent to {@link #subMatrix(long[], long[], ContinuationMode)
* subMatrix}(new long[]{fromX,fromY,fromZ}, new long[]{toX,toY,toZ}, continuationMode)
.
* Note that this matrix must be 3-dimensional
* (in another case IllegalArgumentException
will be thrown).
*
* @param fromX low endpoints (inclusive) of the first coordinate.
* @param fromY low endpoints (inclusive) of the second coordinate.
* @param fromZ low endpoints (inclusive) of the third coordinate.
* @param toX high endpoints (exclusive) of the first coordinate.
* @param toY high endpoints (exclusive) of the second coordinate.
* @param toZ high endpoints (exclusive) of the third coordinate.
* @param continuationMode the value returned while reading elements, lying outside this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if continuationMode
argument is {@code null}.
* @throws IllegalArgumentException if {@link #dimCount()}!=3
.
* @throws IndexOutOfBoundsException for continuationMode=={@link ContinuationMode#NONE}
—
* see {@link Matrix#subMatrix(long[], long[])} method; for other cases —
* or if fromY>toY
or toY-fromY>Long.MAX_VALUE
,
* or if fromZ>toZ
or toZ-fromZ>Long.MAX_VALUE
,
* or if the product (toX-fromX)*(toY-fromY)*(toZ-fromZ)
* (i.e. desired total size of the new matrix)
* is greater than Long.MAX_VALUE
.
* @throws ClassCastException if continuationMode
is {@link
* ContinuationMode#getConstantMode(Object) a constant mode},
* the {@link Matrix.ContinuationMode#continuationConstant()
* continuation constant} is not {@code null} and the class of this
* constant is illegal, i.e.
* cannot be cast to the necessary type according the rules, specified
* for the {@link
* ContinuationMode#getConstantMode(Object) constant continuation mode}.
*/
Matrix subMatrix(
long fromX, long fromY, long fromZ, long toX, long toY, long toZ,
ContinuationMode continuationMode);
/**
* Equivalent to {@link #subMatrix(long[] from, long[] to)} method, where
* from[k]=position[k]
and to[k]=position[k]+dimensions[k]
for all k
.
*
* @param position low endpoints (inclusive) of all coordinates.
* @param dimensions dimensions of the returned submatrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if position
or dimensions
* argument is {@code null}.
* @throws IllegalArgumentException if position.length
or dimensions.length
* is not equal to {@link #dimCount()}.
* @throws IndexOutOfBoundsException if, for some k
,
* position[k]<0 || dimensions[k]<0 ||
* position[k]+dimensions[k]>{@link #dim(int) dim(k)}
.
* @see #subMatr(long[], long[], ContinuationMode)
*/
Matrix subMatr(long[] position, long[] dimensions);
/**
* Equivalent to {@link #subMatr(long[], long[])
* subMatr}(new long[]{x,y}, new long[]{dimX,dimY})
.
* Note that this matrix must be 2-dimensional
* (in another case IllegalArgumentException
will be thrown).
*
* @param x low endpoint (inclusive) of the first coordinate.
* @param y low endpoint (inclusive) of the second coordinate.
* @param dimX the first dimension of the returned submatrix.
* @param dimY the second dimension of the returned submatrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws IllegalArgumentException if {@link #dimCount()}!=2
.
* @throws IndexOutOfBoundsException in the same situations as in {@link #subMatr(long[], long[])}.
*/
Matrix subMatr(long x, long y, long dimX, long dimY);
/**
* Equivalent to {@link #subMatr(long[], long[])
* subMatr}(new long[]{x,y,z}, new long[]{dimX,dimY,dimZ})
.
* Note that this matrix must be 3-dimensional
* (in another case IllegalArgumentException
will be thrown).
*
* @param x low endpoint (inclusive) of the first coordinate.
* @param y low endpoint (inclusive) of the second coordinate.
* @param z low endpoint (inclusive) of the third coordinate.
* @param dimX the first dimension of the returned submatrix.
* @param dimY the second dimension of the returned submatrix.
* @param dimZ the third dimension of the returned submatrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws IllegalArgumentException if {@link #dimCount()}!=2
.
* @throws IndexOutOfBoundsException in the same situations as in {@link #subMatr(long[], long[])}.
*/
Matrix subMatr(long x, long y, long z, long dimX, long dimY, long dimZ);
/**
* Equivalent to {@link #subMatrix(long[] from, long[] to, ContinuationMode continuationMode)} method, where
* from[k]=position[k]
and to[k]=position[k]+dimensions[k]
for all k
.
*
* @param position low endpoints (inclusive) of all coordinates.
* @param dimensions dimensions of the returned submatrix.
* @param continuationMode the value returned while reading elements, lying outside this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if position
, dimensions
* or continuationMode
* argument is {@code null}.
* @throws IllegalArgumentException if position.length
or dimensions.length
* is not equal to {@link #dimCount()}.
* @throws IndexOutOfBoundsException for continuationMode=={@link ContinuationMode#NONE}
—
* see {@link Matrix#subMatr(long[], long[])} method; for other cases —
* if, for some k
, dimensions[k]<0
* or position[k]+dimensions[k]>Long.MAX_VALUE
,
* or if the product of all dimensions[k]
* (i.e. desired total size of the new matrix)
* is greater than Long.MAX_VALUE
.
* @throws ClassCastException if continuationMode
is {@link
* ContinuationMode#getConstantMode(Object) a constant mode},
* the {@link Matrix.ContinuationMode#continuationConstant()
* continuation constant} is not {@code null} and the class of this
* constant is illegal, i.e.
* cannot be cast to the necessary type according the rules, specified
* for the {@link
* ContinuationMode#getConstantMode(Object) constant continuation mode}.
* @see #subMatr(long[], long[])
*/
Matrix subMatr(long[] position, long[] dimensions, ContinuationMode continuationMode);
/**
* Equivalent to {@link #subMatr(long[], long[], ContinuationMode)
* subMatr}(new long[]{x,y}, new long[]{dimX,dimY}, continuationMode)
.
* Note that this matrix must be 2-dimensional
* (in another case IllegalArgumentException
will be thrown).
*
* @param x low endpoint (inclusive) of the first coordinate.
* @param y low endpoint (inclusive) of the second coordinate.
* @param dimX the first dimension of the returned submatrix.
* @param dimY the second dimension of the returned submatrix.
* @param continuationMode the value returned while reading elements, lying outside this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if continuationMode
argument is {@code null}.
* @throws IllegalArgumentException if {@link #dimCount()}!=2
.
* @throws IndexOutOfBoundsException for continuationMode=={@link ContinuationMode#NONE}
—
* see {@link Matrix#subMatr(long[], long[])} method; for other cases —
* if dimX<0
, dimY<0
,
* x+dimX>Long.MAX_VALUE
* or y+dimY>Long.MAX_VALUE
,
* or if the product dimX*dimY
* (i.e. desired total size of the new matrix)
* is greater than Long.MAX_VALUE
.
* @throws ClassCastException if continuationMode
is {@link
* ContinuationMode#getConstantMode(Object) a constant mode},
* the {@link Matrix.ContinuationMode#continuationConstant()
* continuation constant} is not {@code null} and the class of this
* constant is illegal, i.e.,
* cannot be cast to the necessary type according the rules, specified
* for the {@link
* ContinuationMode#getConstantMode(Object) constant continuation mode}.
*/
Matrix subMatr(long x, long y, long dimX, long dimY, ContinuationMode continuationMode);
/**
* Equivalent to {@link #subMatr(long[], long[], ContinuationMode)
* subMatr}(new long[]{x,y,z}, new long[]{dimX,dimY,dimZ}, continuationMode)
.
* Note that this matrix must be 3-dimensional (otherwise, IllegalArgumentException
will be thrown).
*
* @param x low endpoint (inclusive) of the first coordinate.
* @param y low endpoint (inclusive) of the second coordinate.
* @param z low endpoint (inclusive) of the third coordinate.
* @param dimX the first dimension of the returned submatrix.
* @param dimY the second dimension of the returned submatrix.
* @param dimZ the third dimension of the returned submatrix.
* @param continuationMode the value returned while reading elements, lying outside this matrix.
* @return a view of the specified rectangular fragment within this matrix.
* @throws NullPointerException if continuationMode
argument is {@code null}.
* @throws IllegalArgumentException if {@link #dimCount()}!=3
.
* @throws IndexOutOfBoundsException for continuationMode=={@link ContinuationMode#NONE}
—
* see {@link Matrix#subMatr(long[], long[])} method; for other cases —
* if dimX<0
, dimY<0
, dimZ<0
,
* x+dimX>Long.MAX_VALUE
, y+dimY>Long.MAX_VALUE
* or z+dimZ>Long.MAX_VALUE
,
* or if the product dimX*dimY*dimZ
* (i.e. desired total size of the new matrix)
* is greater than Long.MAX_VALUE
.
* @throws ClassCastException if continuationMode
is {@link
* ContinuationMode#getConstantMode(Object) a constant mode},
* the {@link Matrix.ContinuationMode#continuationConstant()
* continuation constant} is not {@code null} and the class of this
* constant is illegal, i.e.
* cannot be cast to the necessary type according the rules, specified
* for the {@link
* ContinuationMode#getConstantMode(Object) constant continuation mode}.
*/
Matrix subMatr(
long x, long y, long z, long dimX, long dimY, long dimZ,
ContinuationMode continuationMode);
/**
* Returns true
if and only if this matrix is a {@link #subMatrix(long[], long[]) submatrix} of
* some parent
matrix, created by one of calls parent.subMatrix(...)
,
* parent.subMatr(...)
or equivalent.
* The {@link #subMatrixParent()} method throws {@link NotSubMatrixException}
* if and only if this method returns false
.
*
* @return whether this object is created by subMatrix(...)
,
* subMatr(...)
or equivalent call.
* @see #subMatrix(long[], long[])
* @see #subMatrix(long[], long[], ContinuationMode)
* @see #subMatr(long[], long[])
* @see #subMatr(long[], long[], ContinuationMode)
* @see #subMatrixParent()
*/
boolean isSubMatrix();
/**
* If this matrix is a {@link #subMatrix(long[], long[]) submatrix} of some parent
matrix,
* created by one of calls parent.subMatrix(...)
or parent.subMatr(...)
,
* returns a reference to the parent
matrix instance.
* If this matrix is not a submatrix, throws {@link NotSubMatrixException}.
*
* @return a reference to the parent matrix, if this instance is a submatrix.
* @throws NotSubMatrixException if this object is not created by subMatrix(...)
,
* subMatr(...)
or equivalent call.
* @see #isSubMatrix()
*/
Matrix subMatrixParent() throws NotSubMatrixException;
/**
* If this matrix is a {@link #subMatrix(long[], long[]) submatrix} of some parent
matrix,
* created by one of calls parent.subMatrix(...)
or parent.subMatr(...)
,
* creates and returns a new Java array containing the starting position of this submatrix
* in the parent one. The result will be equal to "from
" argument of
* {@link #subMatrix(long[], long[])} and {@link #subMatrix(long[], long[], ContinuationMode)} methods.
* If this matrix is not a submatrix, throws {@link NotSubMatrixException}.
*
* @return low endpoints (inclusive) of all coordinates of this submatrix in its parent matrix.
* @throws NotSubMatrixException if this object is not created by subMatrix(...)
,
* subMatr(...)
or equivalent call.
* @see #isSubMatrix()
*/
long[] subMatrixFrom() throws NotSubMatrixException;
/**
* If this matrix is a {@link #subMatrix(long[], long[]) submatrix} of some parent
matrix,
* created by one of calls parent.subMatrix(...)
or parent.subMatr(...)
,
* creates and returns a new Java array containing the ending position (exclusive) of this submatrix
* in the parent one. The result will be equal to "to
" argument of
* {@link #subMatrix(long[], long[])} and {@link #subMatrix(long[], long[], ContinuationMode)} methods.
* If this matrix is not a submatrix, throws {@link NotSubMatrixException}.
*
* @return low endpoints (inclusive) of all coordinates of this submatrix in its parent matrix.
* @throws NotSubMatrixException if this object is not created by subMatrix(...)
,
* subMatr(...)
or equivalent call.
* @see #isSubMatrix()
*/
long[] subMatrixTo() throws NotSubMatrixException;
/**
* If this matrix is a {@link #subMatrix(long[], long[], Matrix.ContinuationMode) submatrix}
* of some parent
matrix,
* created by one of calls parent.subMatrix(...)
or parent.subMatr(...)
,
* returns the {@link ContinuationMode continuation mode}, used by this submatrix.
* If this matrix is not a submatrix, throws {@link NotSubMatrixException}.
*
* If the submatrix was created by
* {@link #subMatrix(long[], long[], net.algart.arrays.Matrix.ContinuationMode)} or equivalent method,
* the continuationMode
argument, passed to that method, is returned.
* If the submatrix was created by
* {@link #subMatrix(long[], long[])} or equivalent method,
* {@link ContinuationMode#NONE} constant is returned.
*
* @return low endpoints (inclusive) of all coordinates of this submatrix in its parent matrix.
* @throws NotSubMatrixException if this object is not created by subMatrix(...)
,
* subMatr(...)
or equivalent call.
* @see #isSubMatrix()
*/
ContinuationMode subMatrixContinuationMode() throws NotSubMatrixException;
/**
* Returns a view ot this matrix, where the elements are reordered in some order "like"
* in the specified matrix m
.
* In other words, the elements of the {@link #array() built-in array} of the returned matrix are
* the same as the elements of the {@link #array() built-in array} of this one
* (any changes of the elements in the returned matrix are reflected in this matrix, and vice versa),
* but the order of the elements can differ. The precise algorithm of reordering is not specified
* and depends on the matrix m
: this method tries to help algorithms, processing the same
* or similar areas in both matrices, to provide maximal performance.
*
*
This method returns non-trivial results only if the matrix m
is already a view of some other
* matrix with some form of reordering elements, for example, if m
is a {@link #isTiled() tiled}
* matrix.
* In another case, this method just returns this instance.
*
*
In the current version of this package (if this instance was created by methods of this package),
* this method is equivalent to the following:
*
*
* m.{@link #isTiled()} ?
* thisInstance.{@link #tile() tile}(m.{@link #tileDimensions()}) :
* thisInstance;
*
*
* In future versions, it is possible that this method will recognize other forms of reordering matrix elements
* and return non-trivial results for such m
matrices.
*
*
Because the precise order of elements of the returning matrix is not specified, we recommend to use
* this method generally for newly created matrices, for example:
*
*
* memoryModel.{@link MemoryModel#newMatrix(Class, Matrix)
* newMatrix}({@link UpdatablePArray}.class, m).{@link #structureLike(Matrix) structureLike}(m);
*
* or, more briefly,
*
* memoryModel.{@link MemoryModel#newStructuredMatrix(Class, Matrix)
* newStructuredMatrix}({@link UpdatablePArray}.class, m);
*
*
* @param m some matrix, probably a view of another matrix with reordered elements
* (for example, {@link #tile(long...) tiled}).
* @return a view of this matrix with elements reordered in similar order, or a reference to this instance
* if m
matrix is not reodered or this method does not "know" about the way of that reordering.
* @throws NullPointerException if m
argument is {@code null}.
* @see #isStructuredLike(Matrix)
*/
Matrix structureLike(Matrix> m);
/**
* Returns true
if the elements of this matrix is ordered "alike" the elements
* of the specified matrix m
, in terms of {@link #structureLike(Matrix)} method.
* "Ordered alike" does not mean that the dimensions of both matrices are equal, or that
* the details of the structure are the same; it means only that both matrices use similar
* reordering algorithms.
*
* More precisely, {@link #structureLike(Matrix)} method returns this instance if and only if
* this method returns true
.
*
*
In the current version of this package (if this instance was created by means of methods of this package),
* this method is equivalent to: thisInstance.{@link #isTiled()}==m.{@link #isTiled()}
.
*
* @param m some matrix, probably a view of another matrix with reordered elements
* (for example, {@link #tile(long...) tiled}).
* @return whether this matrix is reordered alike m
.
* @throws NullPointerException if m
argument is {@code null}.
*/
boolean isStructuredLike(Matrix> m);
/**
* Returns a view ot this matrix, where the elements are reordered by tiles: a grid of rectangular
* regions (tiles), the sizes of which are specified by tileDim
argument.
* It means that the elements of the built-in AlgART array of the returned matrix are the elements
* of the built-in array of this one, but "shuffled" so that all elements of every tile in the returned matrix
* are located in a continuous block of the built-in array of this matrix.
* The returned matrix is named tiled matrix. The {@link #dimensions() dimensions}
* of the returned matrix are the same as the dimensions of this one.
* The {@link #elementType() element type} of the returned matrix is identical to the element type
* of this matrix.
*
*
More precisely, let this matrix be M and the tiled matrix, returned by this method, be T.
* Let i0, i1, ..., in−1
* (n={@link #dimCount()}
) be coordinates of some element it the tiled matrix T,
* that is located in T.{@link #array() array()}
* at the index i=T.{@link #index(long...)
* index}
(i0,i1,...,in−1).
* This element is located in the original array M.{@link #array() array()}
at another index
* j, which is calculated by the following algorithm.
*
*
* - Let dk = M.{@link #dim(int) dim}(k),
* k=0,1,...,n−1: dimensions of this and returned matrix.
*
* - Let i'k = ik%
tileDim[k]
,
* k=0,1,...,n−1: i'k are the coordinates of this element inside
* the tile, containing it in T matrix.
*
* - Let sk = ik−i'k,
* k=0,1,...,n−1: sk are the coordinates of the starting element
* of the tile, containing this element in T matrix.
*
* - Let tk =
min
(tileDim[
k]
,
* dk−sk),
* k=0,1,...,n−1: tk are the dimensions
* of the tile, containing this element in T matrix. (Note that boundary tiles can be less
* than tileDim
, if dimensions of matrix are not divisible by corresponding dimensions of tiles.)
*
* - Let
previousVolume
=
* d0d1...dn−3dn−2sn−1
* + d0d1...dn−3cn−2tn−1
* + ... + s0t1...tn−2tn−1.
* This complex formula returns the summary sizes of all tiles, that are fully located
* in the source T.{@link #array() array()}
before the given element.
* In 2-dimensional case, the formula is more simple:
* previousVolume
= dxsy
* + sxty.
*
*
* - Let
indexInTile
=
* i'0 + i'1t0 + ...
* + i'n−1tn−2...t0:
* it is the index of the element with coordinates
* i'0,i'1,...,i'n−1
* in the built-in array of a little matrix, dimensions of which are equal to the tile dimensions.
*
*
* - The required index of the given element in the original array
* M
.{@link #array() array()}
* is j = previousVolume
+ indexInTile
.
*
*
* Tiled matrices are necessary to provide good performance of many algorithms, if this matrix is very large
* (much greater than amount of RAM) and is located on disk or other external devices.
* For example, extracting a rectangular area 1000x1000 from a byte matrix 1000000x1000000 (1 terabyte)
* will probably work much faster if it is tiled, than if it is a usual matrix, where every line
* occupies 1 MB of continuous disk space.
*
*
In the degenerated case of 1-dimensional matrix ({@link #dimCount()}=1)
* the tiled matrix is absolutely useless, though still works correctly.
*
*
Recommended tile dimensions are from several hundreds to several thousands, but it depends
* on the number of dimensions. If tile dimensions are degrees of two (2k),
* the tiled matrix will probably work faster.
*
*
The built-in AlgART array of the returned matrix is backed by the built-in array of this matrix,
* so — if this matrix is not {@link #isImmutable() immutable}
* — any changes of the elements of the returned matrix are reflected in this matrix, and vice versa.
* The returned matrix is {@link #isImmutable() immutable} if, and only if,
* the built-in array of this matrix does not implement {@link UpdatableArray}.
* The {@link Array#asTrustedImmutable()} method
* in the built-in array of the returned matrix is equivalent to {@link Array#asImmutable()},
* and {@link Array#asCopyOnNextWrite()} method just returns the full copy of the array.
*
* @param tileDim dimensions of the tiles in the returned matrix (excepting the boundary tiles,
* which can be less).
* @return a tiled view of this matrix.
* @throws NullPointerException if tileDim
argument is {@code null}.
* @throws IllegalArgumentException if tileDim.length
is not equal to {@link #dimCount()},
* or if some tileDim[k]<=0
,
* or if the product of all tile dimensions tileDim[k]
* is greater than Long.MAX_VALUE
.
* @see #tile()
* @see #isTiled()
* @see #tileDimensions()
*/
Matrix tile(long... tileDim);
/**
* Returns a tiled view ot this matrix with some default dimensions of the tiles.
* Equivalent to {@link #tile(long...) tile}(tileDim)
, where all elements of tileDim
* are equal to the default integer value, retrieved from the system property
* "net.algart.arrays.matrixTile2D
",
* "net.algart.arrays.matrixTile3D
"
* "net.algart.arrays.matrixTile4D
"
* "net.algart.arrays.matrixTile5D
" or
* "net.algart.arrays.matrixTileND
",
* if the {@link #dimCount() number of dimensions} of this matrix is correspondingly 2, 3, 4, 5 or greater.
* If there is no such property, or if it contains not a number,
* or if some exception occurred while calling Long.getLong
,
* this method uses the following tile dimensions:
* 4096x4096 in 2-dimensional case,
* 256x256x256 in 3-dimensional case,
* 64x64x64x64 in 4-dimensional case,
* 32x32x32x32x32 in 5-dimensional case,
* 16x16x... if the number of dimensions is greater than 5.
* If the corresponding property exists and contains a valid integer number,
* but it is too small, in particular, zero or negative, then it is replaced with some minimal positive value.
* The values of all these system property is loaded and checked only once
* while initializing {@link Arrays} class.
* If the number of dimensions is 1 (degenerated case), this method always uses 65536 as the tile size.
* (Warning! These defaults can be changed in future versions!)
*
* @return a tiled view of this matrix with default tile dimensions.
* @throws IllegalArgumentException if the product of all tile dimensions tileDim[k]
* is greater than Long.MAX_VALUE
.
* @see #tile(long...)
* @see #isTiled()
* @see #tileDimensions()
*/
Matrix tile();
/**
* Returns true
if and only if this matrix is a {@link #tile(long...) tiled view}
* of some parent
matrix, created by a call parent.tile(...)
or an equivalent call.
* The {@link #tileParent()} method throws {@link NotSubMatrixException}
* if and only if this method returns false
.
*
* @return whether this object is created by tile(...)
or equivalent call.
* @see #tile(long...)
* @see #tile()
*/
boolean isTiled();
/**
* If this matrix is a {@link #tile(long...) tiled view} of some parent
matrix,
* created by a call parent.tile(...)
,
* returns a reference to the parent
matrix instance.
* If this matrix is not a tiled view, throws {@link NotTiledMatrixException}.
*
* @return a reference to the parent matrix, if this instance is a tiled view of other matrix.
* @throws NotTiledMatrixException if this object is not created by tile(...)
or equivalent call.
* @see #isTiled()
*/
Matrix tileParent() throws NotTiledMatrixException;
/**
* If this matrix is a {@link #tile(long...) tiled view} of some parent
matrix,
* created by a call parent.tile(...)
,
* creates and returns a new Java array containing the tile dimensions, used while creating this tiled view
* (argument of {@link #tile(long...)} method).
* If this matrix is not a tiled view, throws {@link NotTiledMatrixException}.
*
* @return sizes of each tile, if this instance is a tiled view of other matrix.
* @throws NotTiledMatrixException if this object is not created by tile(...)
or equivalent call.
* @see #isTiled()
*/
long[] tileDimensions() throws NotTiledMatrixException;
/**
* Equivalent to {@link Matrices#asLayers(Matrix) Matrices.asLayers}(thisMatrix)
.
*
* @return a list of matrices: "layers" of this matrix one along the last dimension.
* @throws IllegalStateException if this matrix is 1-dimensional.
*/
default List> asLayers() {
return Matrices.asLayers(this);
}
/**
* Equivalent to {@link #array()}.{@link Array#isImmutable() isImmutable()}
.
*
* There is a guarantee that this method works very quickly.
*
* @return true
if this instance is immutable.
*/
boolean isImmutable();
/**
* Equivalent to {@link #array()}.{@link Array#isCopyOnNextWrite() isCopyOnNextWrite()}
.
*
*
There is a guarantee that this method works very quickly.
*
* @return true
if this instance is copy-on-next-write.
*/
boolean isCopyOnNextWrite();
/**
* Returns true
if and only if the built-in AlgART array implements {@link DirectAccessible}
* interface and (({@link DirectAccessible}){@link #array()}).{@link DirectAccessible#hasJavaArray()
* hasJavaArray()}
method returns true
.
*
*
There is a guarantee that this method works very quickly.
*
* @return whether this matrix can be viewed as a Java array or a part of Java array.
*/
boolean isDirectAccessible();
/**
* Returns an exact clone of this matrix, created in {@link SimpleMemoryModel}.
*
*
For primitive element types, equivalent to
* {@link Matrices#clone(Matrix) Matrices.clone}(thisInstance)
,
* but the generic type of the result is not {@link UpdatableArray updatable}.
* For any types, equivalent to the following operators:
*
* final Matrix<UpdatableArray> result = Arrays.SMM.{@link MemoryModel#newMatrix(Class, Matrix)
* newMatrix}(UpdatableArray.class, thisInstance);
* {@link Matrices#copy(ArrayContext, Matrix, Matrix)
* Matrices.copy}(null, result, thisInstance); // - maximally fast multithreading copying
* (return result)
*
*
* @return exact clone of the passed matrix.
*/
Matrix clone();
/**
* Equivalent to {@link #array()}.{@link Array#flushResources(ArrayContext) flushResources(context)}
.
*
* @param context the context of execution; can be {@code null}, then it will be ignored.
*/
void flushResources(ArrayContext context);
/**
* Equivalent to {@link #array()}.{@link Array#freeResources(ArrayContext) freeResources(context)}
.
*
* @param context the context of execution; can be {@code null}, then it will be ignored.
*/
void freeResources(ArrayContext context);
/**
* Equivalent to {@link #array()}.{@link Array#freeResources() freeResources()}
.
*/
void freeResources();
/**
* Returns a brief string description of this object.
*
* The result of this method may depend on implementation and usually contains
* a short description of the built-in AlgART array and all matrix dimensions.
*
* @return a brief string description of this object.
*/
String toString();
/**
* Returns the hash code of this matrix. The result depends on all elements of the built-in array
* (as {@link Array#hashCode()}) and all matrix dimensions.
*
* @return the hash code of this matrix.
*/
int hashCode();
/**
* Indicates whether some other matrix is equal to this one.
* Returns true
if and only if:
* - the specified object is a matrix (i.e. implements {@link Matrix}),
* - both matrices have the same dimension count ({@link #dimCount()})
* and the same corresponding dimensions;
* - the built-in AlgART arrays ({@link #array()}) are equal (see {@link Array#equals(Object)}).
*
*
* @param obj the object to be compared for equality with this matrix.
* @return true
if the specified object is a matrix equal to this one.
*/
boolean equals(Object obj);
/**
* Equivalent to {@link MemoryModel#newMatrix(Class, Class, long...)
* memoryModel.newMatrix(UpdatablePArray.class, elementType, dim)}
. Throws
* IllegalArgumentException
in a case when the element type is not primitive.
*
* @param memoryModel the memory model, used for allocation new matrix.
* @param elementType the type of matrix elements.
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if elementType
is not a primitive class,
* or if the specified dimensions are incorrect:
* dim.length==0
,
* dim[n] < 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if elementType
is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newMatrix(MemoryModel memoryModel, Class> elementType, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
Objects.requireNonNull(elementType, "Null element type");
if (!elementType.isPrimitive()) {
throw new IllegalArgumentException("Not a primitive type: " + elementType);
}
return memoryModel.newMatrix(UpdatablePArray.class, elementType, dim);
}
/**
* Equivalent to {@link #newMatrix(MemoryModel, Class, long...)
* newMatrix}({@link Arrays#SMM Arrays.SMM}, elementType, dim)
.
*
* @param elementType the type of matrix elements.
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if one of the arguments is {@code null}.
* @throws IllegalArgumentException if elementType
is not a primitive class,
* or if the specified dimensions are incorrect:
* dim.length==0
,
* dim[n] < 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newMatrix(Class> elementType, long... dim) {
return newMatrix(Arrays.SMM, elementType, dim);
}
/*Repeat() boolean ==> char,,byte,,short,,int,,long,,float,,double;;
Bit ==> Char,,Byte,,Short,,Int,,Long,,Float,,Double;;
bit ==> char,,byte,,short,,int,,long,,float,,double */
/**
* Equivalent to {@link MemoryModel#newBitMatrix(long...) memoryModel.newBitMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if boolean
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newBitMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newBitMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newBitMatrix(long...)
* newBitMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newBitMatrix(long... dim) {
return Arrays.SMM.newBitMatrix(dim);
}
/*Repeat.AutoGeneratedStart !! Auto-generated: NOT EDIT !! */
/**
* Equivalent to {@link MemoryModel#newCharMatrix(long...) memoryModel.newCharMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if char
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newCharMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newCharMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newCharMatrix(long...)
* newCharMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newCharMatrix(long... dim) {
return Arrays.SMM.newCharMatrix(dim);
}
/**
* Equivalent to {@link MemoryModel#newByteMatrix(long...) memoryModel.newByteMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if byte
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newByteMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newByteMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newByteMatrix(long...)
* newByteMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newByteMatrix(long... dim) {
return Arrays.SMM.newByteMatrix(dim);
}
/**
* Equivalent to {@link MemoryModel#newShortMatrix(long...) memoryModel.newShortMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if short
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newShortMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newShortMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newShortMatrix(long...)
* newShortMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newShortMatrix(long... dim) {
return Arrays.SMM.newShortMatrix(dim);
}
/**
* Equivalent to {@link MemoryModel#newIntMatrix(long...) memoryModel.newIntMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if int
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newIntMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newIntMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newIntMatrix(long...)
* newIntMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newIntMatrix(long... dim) {
return Arrays.SMM.newIntMatrix(dim);
}
/**
* Equivalent to {@link MemoryModel#newLongMatrix(long...) memoryModel.newLongMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if long
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newLongMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newLongMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newLongMatrix(long...)
* newLongMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newLongMatrix(long... dim) {
return Arrays.SMM.newLongMatrix(dim);
}
/**
* Equivalent to {@link MemoryModel#newFloatMatrix(long...) memoryModel.newFloatMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if float
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newFloatMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newFloatMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newFloatMatrix(long...)
* newFloatMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newFloatMatrix(long... dim) {
return Arrays.SMM.newFloatMatrix(dim);
}
/**
* Equivalent to {@link MemoryModel#newDoubleMatrix(long...) memoryModel.newDoubleMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws UnsupportedElementTypeException if double
element type
* is not supported by this memory model.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for this memory model.
*/
static Matrix newDoubleMatrix(MemoryModel memoryModel, long... dim) {
Objects.requireNonNull(memoryModel, "Null memory model");
return memoryModel.newDoubleMatrix(dim);
}
/**
* Equivalent to {@link Arrays#SMM Arrays.SMM}.{@link MemoryModel#newDoubleMatrix(long...)
* newDoubleMatrix(dim)}
.
*
* @param dim the dimensions of the matrix.
* @return created matrix.
* @throws NullPointerException if dim
is {@code null}.
* @throws IllegalArgumentException if the specified dimensions are incorrect: dim.length == 0
,
* dim[n] <= 0
for some n
,
* or the product of all specified dimensions
* is greater than Long.MAX_VALUE
.
* @throws TooLargeArrayException if the product of all specified dimensions is too large
* for {@link SimpleMemoryModel}.
*/
static Matrix newDoubleMatrix(long... dim) {
return Arrays.SMM.newDoubleMatrix(dim);
}
/*Repeat.AutoGeneratedEnd*/
/**
* Equivalent to {@link SimpleMemoryModel#asMatrix(Object, long...)}
* SimpleMemoryModel.asMatrix}(array, dim)
.
*
* @param array the source Java array.
* @param dim the matrix dimensions.
* @return a matrix backed by the specified Java array with the specified dimensions.
* @throws NullPointerException if array
or dim
argument is {@code null}.
* @throws IllegalArgumentException if array
argument is not a Java array
* and is not {@link UpdatablePArray},
* or if it is boolean[]
array, or array of objects,
* or if the number of dimensions is 0 (empty dim
Java array),
* or if some of the dimensions are negative.
* @throws SizeMismatchException if the product of all dimensions is not equal to the array length.
* @throws TooLargeArrayException if the product of all dimensions is greater than Long.MAX_VALUE
.
*/
static Matrix as(Object array, long... dim) {
return SimpleMemoryModel.asMatrix(array, dim);
}
}