org.nuiton.math.matrix.DoubleVector 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 org.apache.commons.collections.primitives.ArrayDoubleList;
/**
* Permet de stocker des données à une position lineaire et de la redemander.
* Cette classe ne gére que les données lineaire. L'avantage de cette classe est
* de ne conserver que les elements differents de la valeur par defaut, ce qui
* minimize la taille du tableau necessaire a conserver les données.
*
* Created: 6 octobre 2005 01:29:23 CEST
*
* @author Benjamin POUSSIN
* @version $Revision: 187 $
*
* Last update: $Date: 2009-10-16 19:17:29 +0200 (ven., 16 oct. 2009) $
* by : $Author: tchemit $
*/
public class DoubleVector implements Vector { // FloatVector
/** maximum number of element, maximum pos value */
protected int capacity = 0;
/** la valeur par defaut */
protected double defaultValue = 0;
/** contient la position de l'element, le tableau est trie */
protected int[] position;
protected int positionSize = 0;
/** contient la valeur de l'element */
protected ArrayDoubleList data = new ArrayDoubleList();
public DoubleVector(int capacity) {
this.capacity = capacity;
position = new int[8];
Arrays.fill(position, Integer.MAX_VALUE);
}
public DoubleVector(int capacity, double defaultValue) {
this(capacity);
this.defaultValue = defaultValue;
}
@Override
public int size() {
return capacity;
}
// poussin 20060827 TODO: verifier l'implantation, il semble quelle soit
// fausse et ne puisse pas recherche le nombre max correctement
@Override
public double getMaxOccurence() {
double result = defaultValue;
double[] tmp = data.toArray();
// si potentiellement il y a plus d'element identique dans data
// que de valeur par defaut, on recherche la valeur possible
if (this.capacity < 2 * tmp.length) {
Arrays.sort(tmp);
// le nombre de fois que l'on a rencontrer la valeur la plus
// nombreuse
int max = 1;
// le nombre de fois que l'on a rencontrer la valeur courante
int count = 1;
// la valeur la plus rencontrer
result = tmp[0];
// la valeur que l'on vient de traiter précédement
double old = tmp[0];
// la valeur courante lu dans le tableaux
double current = tmp[0];
// tant que l'on peut encore trouve un element plus nombreux dans le
// tableau on le parcours
for (int i = 1; max < tmp.length - i + count && i < tmp.length; i++) {
current = tmp[i];
if (current == old) {
count++;
} else {
if (count > max) {
max = count;
result = old;
}
count = 1;
old = current;
}
}
if (count > max) {
max = count;
result = current;
}
if (max <= capacity - tmp.length) {
// en fin de compte, il n'y a pas plus d'element identique
// dans data que de defaultValue
result = defaultValue;
}
}
return result;
}
protected void checkPos(int pos) {
if (pos < 0 || pos >= capacity) {
throw new IllegalArgumentException("pos " + pos + " is not in [0, "
+ capacity + "]");
}
}
@Override
public double getValue(int pos) {
checkPos(pos);
double result = defaultValue;
int index = findIndex(pos);
if (index >= 0) {
result = data.get(index);
}
return result;
}
@Override
public void setValue(int pos, double value) {
checkPos(pos);
int index = findIndex(pos);
if (index >= 0) {
if (value == defaultValue) {
// il etait present, on supprime l'element
removeElementAt(index);
data.removeElementAt(index);
} else {
// il etait deja present, on modifie la valeur
data.set(index, value);
}
} else {
// il n'etait pas present
if (value != defaultValue) {
// il faut ajouter dans position et dans data
index = -index - 1;
addElementAt(index, pos);
data.add(index, value);
}
}
}
@Override
public boolean equals(Object o) {
boolean result = false;
if (o instanceof DoubleVector) {
DoubleVector other = (DoubleVector) o;
result = Arrays.equals(this.position, other.position)
&& data.equals(other.data);
} else if (o instanceof Vector) {
Vector other = (Vector) o;
result = true;
for (int i = 0; i < size() && result; i++) {
result = getValue(i) == other.getValue(i);
}
}
return result;
}
/**
* retourne la position dans le tableau position de la position lineaire
*
* @param pos
* @return la position ou < 0 donnant la position de l'element s'il etait
* present
*/
protected int findIndex(int pos) {
return Arrays.binarySearch(position, pos);
}
protected void ensureCapacity(int mincap) {
if (mincap > position.length) {
int newcap = (position.length * 3) / 2 + 1;
int olddata[] = position;
position = new int[newcap >= mincap ? newcap : mincap];
System.arraycopy(olddata, 0, position, 0, positionSize);
for (int i = positionSize; i < position.length; i++) {
position[i] = Integer.MAX_VALUE;
}
}
}
protected void addElementAt(int index, int element) {
ensureCapacity(positionSize + 1);
int numtomove = positionSize - index;
System.arraycopy(position, index, position, index + 1, numtomove);
position[index] = element;
positionSize++;
}
protected int removeElementAt(int index) {
int oldval = position[index];
int numtomove = positionSize - index - 1;
if (numtomove > 0) {
System.arraycopy(position, index + 1, position, index, numtomove);
}
positionSize--;
position[positionSize] = Integer.MAX_VALUE;
return oldval;
}
@Override
public boolean isImplementedPaste(Vector v) {
return v instanceof DoubleVector;
}
@Override
public boolean isImplementedAdd(Vector v) {
// FIXME une fois la methode implanter supprimer le false
return false && v instanceof DoubleVector;
}
@Override
public boolean isImplementedMinus(Vector v) {
// FIXME une fois la methode implanter supprimer le false
return false && v instanceof DoubleVector;
}
@Override
public boolean isImplementedMap() {
return true;
}
/**
* On recopie tous les attributs pour que le vector ressemble exactement a
* celui passé en argument
*/
@Override
public void paste(Vector v) {
DoubleVector fbv = (DoubleVector) v;
this.capacity = fbv.capacity;
this.defaultValue = fbv.defaultValue;
this.positionSize = fbv.positionSize;
this.position = new int[fbv.position.length];
System.arraycopy(fbv.position, 0, this.position, 0,
this.position.length);
this.data.clear();
this.data.addAll(fbv.data);
}
// poussin 20060827 FIXME a refaire car v.data et date n'ont pas forcement
// leur element qui se correspondent, cette implatation est donc fausse
@Override
public void add(Vector v) {
DoubleVector fbv = (DoubleVector) v;
for (int i = 0; i < data.size(); i++) {
double newValue = data.get(i) + fbv.data.get(i);
data.set(i, newValue);
}
}
// poussin 20060827 FIXME a refaire car v.data et date n'ont pas forcement
// leur element qui se correspondent, cette implatation est donc fausse
@Override
public void minus(Vector v) {
DoubleVector fbv = (DoubleVector) v;
for (int i = 0; i < data.size(); i++) {
double newValue = data.get(i) - fbv.data.get(i);
data.set(i, newValue);
}
}
/**
* on applique sur chaque donnée existante et sur default
*/
@Override
public void map(MapFunction f) {
// on commence toujours par modifier la valeur par defaut
// car les valeurs suivante pourrait prendre cette valeur
// et donc disparaitre des tableaux si besoin
defaultValue = f.apply(defaultValue);
// on fait la boucle a l'envers au cas ou on supprime des valeurs
for (int i = data.size() - 1; i >= 0; i--) {
double value = f.apply(data.get(i));
if (value == defaultValue) {
// il etait present, on supprime l'element
removeElementAt(i);
data.removeElementAt(i);
} else {
// il etait deja present, on modifie la valeur
data.set(i, value);
}
}
}
} // FloatVector