org.nuiton.math.matrix.BasicMatrix Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nuiton-matrix Show documentation
Show all versions of nuiton-matrix Show documentation
Librairie de matrice multi-dimensions.
The newest version!
/* *##% NuitonMatrix
* Copyright (C) 2004 - 2009 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* . ##%*/
package org.nuiton.math.matrix;
import java.util.Arrays;
import java.util.NoSuchElementException;
import org.nuiton.i18n.I18n;
/**
* Objet matrice qui ne permet que le stockage de double dans un matrice à
* autant de dimension que l'on souhaite.
*
* Created: 27 oct. 2004
*
* @author Benjamin Poussin
* @version $Revision: 179 $
*
* Mise a jour: $Date: 2009-10-08 15:23:44 +0200 (jeu., 08 oct. 2009) $
* par : $Author: echatellier $
*/
public class BasicMatrix { // BasicMatrix
/** La factory */
protected MatrixFactory factory = null;
/** Les dimensions de la matrice */
protected int[] dimensions = null;
/** La matrice en représentation linéaire */
protected Vector data = null;
/**
* tableau de facteur permettant de convertir les coordonnées dans la
* matrice en un indice dans la représentation linéaire de la matrice
*/
protected int[] linearFactor = null;
/**
* Crée une nouvelle matrice ayant les dimensions demandées.
*
* @param factory factory
* @param dimensions dimensions
*/
public BasicMatrix(MatrixFactory factory, int[] dimensions) {
this.factory = factory;
checkDim(dimensions);
// copie des dimensions pour que personne à l'extérieur de l'objet
// ne puisse les modifiers par la suite
this.dimensions = new int[dimensions.length];
System.arraycopy(dimensions, 0, this.dimensions, 0, dimensions.length);
// calcul du linearFactor
linearFactor = new int[dimensions.length];
linearFactor[linearFactor.length - 1] = 1;
for (int i = linearFactor.length - 2; i >= 0; i--) {
linearFactor[i] = linearFactor[i + 1] * dimensions[i + 1];
}
// creation de la matrice lineaire
data = factory.createVector(linearFactor[0] * dimensions[0]);
}
/**
* Retourne la valeur la plus courrement rencontrer dans la matrice. si
* plusieurs valeurs ont le même nombre d'occurence la plus petite valeur
* est retourné.
*
* @return la valeur la plus nombreuse dans la matrice, ou la plus petite si
* plusieurs valeur se retourve le même nombre de fois
*/
public double getMaxOccurence() {
return data.getMaxOccurence();
}
/**
* Retourne le nombre de dimension de la matrice
*
* @return le nombre de dimension de la matrice;
*/
public int getNbDim() {
return dimensions.length;
}
/**
* Retourne la taille d'une dimension
*
* @param dim la dimension dont on souhaite la taille
* @return la taille d'une dimension
*/
public int getDim(int dim) {
checkDim(dim);
return dimensions[dim];
}
/**
* Retourne un tableau representant les dimensions de la matrice. Le tableau
* retourné n'est pas une copie, il ne faut donc pas le modifier
*
* @return le tableau des dimensions.
*/
public int[] getDim() {
return dimensions;
}
/**
* Retourne un element de la matrice
*
* @param pos la position de l'element à retourner
* @return un element de la matrice
*/
public double getValue(int[] pos) {
int indice = coordonatesToLinear(pos);
return data.getValue(indice);
}
/**
* Modifie un élement de la matrice
*
* @param pos la position de l'element à modifier
* @param value la nouvelle valeur à mettre dans la matrice
*/
public void setValue(int[] pos, double value) {
int indice = coordonatesToLinear(pos);
data.setValue(indice, value);
}
/**
* Retourne un objet Inc pret a etre utilisé pour boucler sur tous les
* element de la matrice.
*
* @return un objet Inc pret à être utilisé
*/
public BasicMatrixIterator iterator() {
return new BasicMatrixIteratorImpl(this);
}
/**
* Permet de faire un traitement sur chaque valeur de la matrice
*
* @param f la fonction a appliquer à chaque élement de la matrice
*/
public void map(MapFunction f) {
if (data.isImplementedMap()) {
data.map(f);
} else {
for (int i = 0; i < data.size(); i++) {
double result = f.apply(data.getValue(i));
data.setValue(i, result);
}
}
}
/**
* Permet de convertir les coordonnées d'un élément en un indice dans la
* représentation linéraire de la matrice.
*
* @param coordonates les coordonnées à lineariser
* @return un indice réprésentant les coordonnées de façon linéaire
*/
protected int coordonatesToLinear(int[] coordonates) {
checkPos(coordonates);
int result = 0;
for (int i = 0; i < linearFactor.length; i++) {
result += coordonates[i] * linearFactor[i];
}
return result;
}
/**
* Convertie une coordonnée lineaire en coordonnées spaciales
*
* @param pos la coordonnée linéaire
* @return les coordonnées spaciales de l'élément
*/
protected int[] linearToCoordinates(int pos) {
int[] result = new int[linearFactor.length];
for (int i = 0; i < result.length; i++) {
result[i] = pos / linearFactor[i];
pos -= result[i] * linearFactor[i];
}
return result;
}
/**
* Permet de vérifier que les dimensions de la nouvelle matrice sont
* corrects
*
* @param dim les dimensions de la nouvelle matrice
* @throws IllegalArgumentException si une dimension n'est pas valide
*/
protected void checkDim(int[] dim) {
for (int i = 0; i < dim.length; i++) {
if (dim[i] <= 0) {
throw new IllegalArgumentException(I18n._(
"nuitonmatrix.invalid.size", Integer.valueOf(i), Integer
.valueOf(dim[i])));
}
}
}
/**
* Permet de vérifier qu'une dimension demandé existe bien dans la matrice
*
* @param dim la position de la dimension que l'on souhaite
* @throws IndexOutOfBoundsException si la dimension demandée n'existe pas
*/
protected void checkDim(int dim) {
if (dim < 0 || dim >= getNbDim()) {
throw new IndexOutOfBoundsException(I18n._(
"nuitonmatrix.invalid.size", dim, getNbDim()));
}
}
/**
* Verifie que les coordonnées demandé appartiennent bien à la matrice
*
* @param pos les coordonnées souhaitées dans la matrice
* @throws NoSuchElementException si les coordonnées ne correspondent pas à
* un élement de la matrice
*/
protected void checkPos(int[] pos) {
int[] dim = getDim();
boolean result = dim.length == pos.length;
for (int i = 0; result && i < dim.length; i++) {
result = (0 <= pos[i]) && (pos[i] < dim[i]);
}
if (!result) {
throw new NoSuchElementException(I18n._(
"nuitonmatrix.invalid.element", Arrays.toString(pos), Arrays
.toString(dim)));
}
}
@Override
public String toString() {
StringBuffer result = new StringBuffer();
if (getNbDim() == 1) {
result.append("matrix1D [");
for (int i = 0; i < data.size(); i++) {
result.append(data.getValue(i) + ",");
}
result.append("]");
} else if (getNbDim() == 2) {
DimensionHelper dimHelper = new DimensionHelper();
result.append("matrix2D [");
for (int y = 0; y < getDim(1); y++) {
result.append("\n");
for (int x = 0; x < getDim(0); x++) {
result.append(getValue(dimHelper.get(x, y)) + ",");
}
}
result.append("]");
} else {
result.append("dimensions = [\n");
for (int i = 0; i < dimensions.length; i++) {
result.append(dimensions[i] + ",");
}
result.append("\n]\nmatrice = [\n");
for (int i = 0; i < data.size(); i++) {
result.append(data.getValue(i) + ",");
}
result.append("\n]\nlinearFactor = [\n");
for (int i = 0; i < linearFactor.length; i++) {
result.append(linearFactor[i] + ",");
}
result.append("\n]\n");
}
return result.toString();
}
@Override
public boolean equals(Object o) {
if (o instanceof BasicMatrix) {
BasicMatrix other = (BasicMatrix) o;
return this == o
|| (Arrays.equals(this.dimensions, other.dimensions) && this.data
.equals(other.data));
}
return false;
}
protected class BasicMatrixIteratorImpl implements BasicMatrixIterator { // MatrixIteratorImpl
protected BasicMatrix matrix = null;
protected int pos = -1;
/**
* @param matrix la matrice sur lequel l'iterator doit travailler
*/
public BasicMatrixIteratorImpl(BasicMatrix matrix) {
this.matrix = matrix;
pos = -1;
}
@Override
public boolean hasNext() {
return pos + 1 < matrix.data.size();
}
@Override
public boolean next() {
boolean result = false;
if (hasNext()) {
pos++;
return true;
}
return result;
}
@Override
public double getValue() {
return matrix.data.getValue(pos);
}
@Override
public void setValue(double value) {
matrix.data.setValue(pos, value);
}
@Override
public int[] getCoordinates() {
return matrix.linearToCoordinates(pos);
}
} // BasicMatrixIteratorImpl
} // BasicMatrix