r315 - in trunk/nuiton-matrix/src: main/java/org/nuiton/math/matrix test/java/org/nuiton/math/matrix
Author: echatellier Date: 2010-12-16 16:59:22 +0100 (Thu, 16 Dec 2010) New Revision: 315 Url: http://nuiton.org/repositories/revision/nuiton-matrix/315 Log: Add new matrix proxy empty matrix implementation that use provider to fill value after reduction Added: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProvider.java trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProxy.java trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixProxyTest.java Modified: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixFactory.java trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixHelper.java trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixND.java trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java Modified: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java =================================================================== --- trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java 2010-12-16 15:58:02 UTC (rev 314) +++ trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java 2010-12-16 15:59:22 UTC (rev 315) @@ -73,6 +73,10 @@ protected List<?>[] semantics = null; + /** + * @deprecated as of 2.1 seams unused + */ + @Deprecated protected double defaultValue = 0; /** @@ -806,10 +810,28 @@ } @Override + public MatrixND getSubMatrix(Object[]... elems) { + MatrixND result = this; + for (int i = 0; i < elems.length; ++i) { + result = result.getSubMatrix(i, elems[i]); + } + return result; + } + + @Override public MatrixND getSubMatrix(int dim, int[] elem) { return new SubMatrix(this, dim, elem); } + @Override + public MatrixND getSubMatrix(int[]... elems) { + MatrixND result = this; + for (int i = 0; i < elems.length; ++i) { + result = new SubMatrix(result, i, elems[i]); + } + return result; + } + /** * Modifie la matrice actuelle en lui ajoutant les valeurs de la matrice * passé en parametre. La matrice passé en parametre doit avoir le meme Modified: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixFactory.java =================================================================== --- trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixFactory.java 2010-12-16 15:58:02 UTC (rev 314) +++ trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixFactory.java 2010-12-16 15:59:22 UTC (rev 315) @@ -64,7 +64,7 @@ * Retourne une factory utilisant vectorClass comme classe de base a * l'implantation des matrices. * - * @param vectorClass vector class implememantation + * @param vectorClass vector class implementation * @return factory */ public static MatrixFactory getInstance(Class<?> vectorClass) { @@ -165,5 +165,35 @@ throw new RuntimeException("Can't create vector", eee); } } + + public MatrixProxy createProxy(List<?>[] semantics, MatrixProvider matrixProvider) { + MatrixProxy matrixProxy = new MatrixProxy(this, semantics); + matrixProxy.setMatrixProvider(matrixProvider); + return matrixProxy; + } + public MatrixProxy createProxy(String name, int[] dim, MatrixProvider matrixProvider) { + MatrixProxy matrixProxy = new MatrixProxy(this, name, dim); + matrixProxy.setMatrixProvider(matrixProvider); + return matrixProxy; + } + + public MatrixProxy createProxy(String name, int[] dim, String[] dimNames, MatrixProvider matrixProvider) { + MatrixProxy matrixProxy = new MatrixProxy(this, name, dim, dimNames); + matrixProxy.setMatrixProvider(matrixProvider); + return matrixProxy; + } + + public MatrixProxy createProxy(String name, List<?>[] semantics, MatrixProvider matrixProvider) { + MatrixProxy matrixProxy = new MatrixProxy(this, name, semantics); + matrixProxy.setMatrixProvider(matrixProvider); + return matrixProxy; + } + + public MatrixProxy createProxy(String name, List<?>[] semantics, String[] dimNames, MatrixProvider matrixProvider) { + MatrixProxy matrixProxy = new MatrixProxy(this, name, semantics, dimNames); + matrixProxy.setMatrixProvider(matrixProvider); + return matrixProxy; + } + } // MatrixFactory Modified: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixHelper.java =================================================================== --- trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixHelper.java 2010-12-16 15:58:02 UTC (rev 314) +++ trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixHelper.java 2010-12-16 15:59:22 UTC (rev 315) @@ -32,6 +32,8 @@ import java.util.NoSuchElementException; import java.util.Stack; +import org.apache.commons.lang.ArrayUtils; + /** * Contains usefull methods to get information on matrix. * Modified: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixND.java =================================================================== --- trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixND.java 2010-12-16 15:58:02 UTC (rev 314) +++ trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixND.java 2010-12-16 15:59:22 UTC (rev 315) @@ -656,12 +656,34 @@ * prend que certain élément. * * @param dim la dimension dans lequel on veut une sous matrice - * @param elem les éléments dans la dimension à conserver + * @param elem les indices des éléments dans la dimension à conserver * @return new matrix */ public MatrixND getSubMatrix(int dim, int[] elem); /** + * Permet de prendre une sous matrice dans la matrice courante. + * + * Réalise plusieurs appels à {@link #getSubMatrix(int, Object...)} suivant + * l'implémentation. + * + * @param elem les éléments dans la dimension à conserver + * @return new matrix + */ + public MatrixND getSubMatrix(Object[]... elem); + + /** + * Permet de prendre une sous matrice dans la matrice courante. + * + * Réalise plusieurs appels a {@link #getSubMatrix(int, int[])} suivant + * l'implementation. + * + * @param elems les indices des éléments pour chaque dimension à conserver + * @return new matrix + */ + public MatrixND getSubMatrix(int[]... elems); + + /** * Addition la matrice courante avec la matrice passe en parametre et se * retourne elle meme. * Added: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProvider.java =================================================================== --- trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProvider.java (rev 0) +++ trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProvider.java 2010-12-16 15:59:22 UTC (rev 315) @@ -0,0 +1,47 @@ +/* + * #%L + * + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2010 Codelutin, Chatellier Eric + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.math.matrix; + +/** + * Matrix provider used by {@link MatrixProxy} to fill matrix value after + * dimensions reductions. + * + * @author chatellier + * @version $Revision$ + * + * Last update : $Date$ + * By : $Author$ + */ +public interface MatrixProvider { + + /** + * Fill a matrix after dimensions reductions. + * + * @param matrix matrix to fill + */ + public void fillValues(MatrixND matrix); + +} Property changes on: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProvider.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProxy.java =================================================================== --- trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProxy.java (rev 0) +++ trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProxy.java 2010-12-16 15:59:22 UTC (rev 315) @@ -0,0 +1,181 @@ +/* + * #%L + * + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2010 Codelutin, Chatellier Eric + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.math.matrix; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang.ArrayUtils; + +/** + * Matrix proxy contains only dimension and semantics definition, but + * does not allocate memory spaces for value. + * Call to getSubMatrix method will return a really allocated memory + * matrix and use a {@link MatrixProvider} to fill matrix value. + * + * This is usefull for huge matrix that need to not be filled at first + * use, but after some dimensions reductions. + * + * @author chatellier + * @version $Revision$ + * + * Last update : $Date$ + * By : $Author$ + * + * @see MatrixProvider + */ +public class MatrixProxy extends AbstractMatrixND { + + /** serialVersionUID. */ + private static final long serialVersionUID = 2338394722090201478L; + + protected MatrixProvider matrixProvider; + + protected MatrixProxy(MatrixFactory factory, int[] dim) { + super(factory, dim); + } + + protected MatrixProxy(MatrixFactory factory, List<?>[] semantics) { + super(factory, semantics); + } + + protected MatrixProxy(MatrixFactory factory, String name, int[] dim) { + super(factory, name, dim); + } + + protected MatrixProxy(MatrixFactory factory, String name, int[] dim, + String[] dimNames) { + super(factory, name, dim, dimNames); + } + + protected MatrixProxy(MatrixFactory factory, String name, + List<?>[] semantics) { + super(factory, name, semantics); + } + + protected MatrixProxy(MatrixFactory factory, String name, + List<?>[] semantics, String[] dimNames) { + super(factory, name, semantics, dimNames); + } + + public MatrixProvider getMatrixProvider() { + return matrixProvider; + } + + public void setMatrixProvider(MatrixProvider matrixProvider) { + this.matrixProvider = matrixProvider; + } + + /* + * @see org.nuiton.math.matrix.AbstractMatrixND#iterator() + */ + @Override + public MatrixIterator iterator() { + throw new UnsupportedOperationException("Not implemented on matrix proxy"); + } + + /* + * @see org.nuiton.math.matrix.AbstractMatrixND#getValue(int[]) + */ + @Override + public double getValue(int[] coordinates) { + throw new UnsupportedOperationException("Not implemented on matrix proxy"); + } + + /* + * @see org.nuiton.math.matrix.AbstractMatrixND#setValue(int[], double) + */ + @Override + public void setValue(int[] coordinates, double d) { + throw new UnsupportedOperationException("Not implemented on matrix proxy"); + } + + @Override + public MatrixND getSubMatrix(int dim, int start, int nb) { + //TODO echatellier 20101216 could be implemented + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public MatrixND getSubMatrix(int dim, Object... elem) { + //TODO echatellier 20101216 could be implemented + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public MatrixND getSubMatrix(Object[]... elems) { + + // convert semantics to indices + int[][] elemIndices = new int[elems.length][]; + for (int i = 0 ; i < elemIndices.length ; ++i) { + if (elems[i] != null) { + elemIndices[i] = new int[elems[i].length]; + for (int j = 0; j < elems[i].length; j++) { + elemIndices[i][j] = MatrixHelper.indexOf(getSemantics(), i, elems[i][j]); + } + } + } + + MatrixND subMatrix = getSubMatrix(elemIndices); + return subMatrix; + } + + @Override + public MatrixND getSubMatrix(int dim, int[] elem) { + //TODO echatellier 20101216 could be implemented + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public MatrixND getSubMatrix(int[]... elems) { + + // la reduction doit se faire sur le meme nombre de dimension + if (elems.length != dim.length) { + throw new IllegalArgumentException(String.format("Can't reduce matrix with different dimension count (expected: %d, got %d)", dim.length, elems.length)); + } + + // recopie seulement des sous semantiques voulues + // a partir des semantics du parent (super) + List<Object>[] subSem = new List[elems.length]; + for (int iDim = 0 ; iDim < elems.length ; iDim++) { + subSem[iDim] = new ArrayList<Object>(); + List<?> semantics = super.semantics[iDim]; + + for (int iElem = 0; iElem < semantics.size(); iElem++) { + // si c'est null, on copies tout + if (elems[iDim] == null || ArrayUtils.contains(elems[iDim], iElem)) { + subSem[iDim].add(semantics.get(iElem)); + } + } + } + + MatrixND subMatrix = factory.create(name, subSem, dimNames); + matrixProvider.fillValues(subMatrix); + return subMatrix; + } + +} Property changes on: trunk/nuiton-matrix/src/main/java/org/nuiton/math/matrix/MatrixProxy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java =================================================================== --- trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java 2010-12-16 15:58:02 UTC (rev 314) +++ trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java 2010-12-16 15:59:22 UTC (rev 315) @@ -429,7 +429,92 @@ Assert.assertEquals(3.0, mat.getValue(5, 0, 3), 0); } + /** + * Test de reduction simple par indice. + * + * @throws Exception + */ @Test + public void testSubMatrixIntIntArray() throws Exception { + List<String> s1 = Arrays.asList(new String[] { "a", "b", "c" }); + List<String> s2 = Arrays.asList(new String[] { "e", "f", "g" }); + List<String> s3 = Arrays.asList(new String[] { "k", "l", "m" }); + + MatrixND mat = getFactory().create("Ma mat", new List[] { s1, s2, s3 }, + new String[] { "dim abc", "dim efg", "dim klm" }); + + // reduction de "e", "f", "g" en "f", "g" + MatrixND mat2 = mat.getSubMatrix(1, new int[]{1,2}); + Assert.assertEquals(new String[]{"f","g"}, mat2.getSemantic(1)); + mat2 = mat2.getSubMatrix(2, new int[]{2}); + Assert.assertEquals(new String[]{"m"}, mat2.getSemantic(2)); + } + + /** + * Test de reduction simple par semantic. + * + * @throws Exception + */ + @Test + public void testSubMatrixIntObjectArray() throws Exception { + List<String> s1 = Arrays.asList(new String[] { "a", "b", "c" }); + List<String> s2 = Arrays.asList(new String[] { "e", "f", "g" }); + List<String> s3 = Arrays.asList(new String[] { "k", "l", "m" }); + + MatrixND mat = getFactory().create("Ma mat", new List[] { s1, s2, s3 }, + new String[] { "dim abc", "dim efg", "dim klm" }); + + // reduction de "e", "f", "g" en "f", "g" + MatrixND mat2 = mat.getSubMatrix(1, "f", "g"); + Assert.assertEquals(new String[]{"f","g"}, mat2.getSemantic(1)); + mat2 = mat2.getSubMatrix(2, "m"); + Assert.assertEquals(new String[]{"m"}, mat2.getSemantic(2)); + } + + /** + * Test de reduction multiple par indices. + * + * @throws Exception + */ + @Test + public void testSubMatrixIntArrayArray() throws Exception { + List<String> s1 = Arrays.asList(new String[] { "a", "b", "c" }); + List<String> s2 = Arrays.asList(new String[] { "e", "f", "g" }); + List<String> s3 = Arrays.asList(new String[] { "k", "l", "m" }); + + MatrixND mat = getFactory().create("Ma mat", new List[] { s1, s2, s3 }, + new String[] { "dim abc", "dim efg", "dim klm" }); + + // reduction de "e", "f", "g" en "f", "g" et "k", "l", "m" en "m" + MatrixND mat2 = mat.getSubMatrix(new int[][]{new int[]{0, 1, 2}, new int[]{1,2}, new int[]{2}}); + Assert.assertEquals(new String[]{"f","g"}, mat2.getSemantic(1)); + Assert.assertEquals(new String[]{"m"}, mat2.getSemantic(2)); + + // meme test avec des null + mat2 = mat.getSubMatrix(new int[][]{null, new int[]{1,2}, new int[]{2}}); + Assert.assertEquals(new String[]{"f","g"}, mat2.getSemantic(1)); + Assert.assertEquals(new String[]{"m"}, mat2.getSemantic(2)); + } + + /** + * Test de reduction sur le mauvais nombre de dimension. + * + * @throws Exception + */ + @Test(expected=IllegalArgumentException.class) + public void testSubMatrixIntArrayArrayException() throws Exception { + List<String> s1 = Arrays.asList(new String[] { "a", "b", "c" }); + List<String> s2 = Arrays.asList(new String[] { "e", "f", "g" }); + List<String> s3 = Arrays.asList(new String[] { "k", "l", "m" }); + + MatrixND mat = getFactory().create("Ma mat", new List[] { s1, s2, s3 }, + new String[] { "dim abc", "dim efg", "dim klm" }); + + // reduction de "e", "f", "g" en "f", "g" + mat.getSubMatrix(new int[][]{null}); + } + + @Test public void testTranspose() throws Exception { MatrixND mat = null; Added: trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixProxyTest.java =================================================================== --- trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixProxyTest.java (rev 0) +++ trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixProxyTest.java 2010-12-16 15:59:22 UTC (rev 315) @@ -0,0 +1,122 @@ +/* + * #%L + * + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2010 Codelutin, Chatellier Eric + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.math.matrix; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; + +/** + * Test about matrix proxy and provider class. + * + * @author chatellier + * @version $Revision$ + * + * Last update : $Date$ + * By : $Author$ + */ +public class MatrixProxyTest { + + private static final Log log = LogFactory.getLog(MatrixProxyTest.class); + + public MatrixFactory getFactory() throws Exception { + return MatrixFactory.getInstance(DoubleVector.class); + } + + static class MatrixTestProvider implements MatrixProvider { + @Override + public void fillValues(MatrixND matrix) { + MatrixHelper.fill(matrix, 10.0); + } + } + + protected MatrixND getTestProxy(int dim) throws Exception { + + List<String> years = new ArrayList<String>(); + List<String> cities = new ArrayList<String>(); + List<String> quarter = new ArrayList<String>(); + for (int i = 0 ; i < dim ; i ++) { + years.add("200" + i); + cities.add("City " + i); + quarter.add("Quarter " + i); + } + + MatrixProxy matrix = getFactory().createProxy("test matrix", new List<?>[] { years, cities, quarter}, + new String[] {"Years", "Cities", "Quarter"}, new MatrixTestProvider()); + return matrix; + } + + /** + * Test de manipuler la matrice comme une matrice normale + * et que ses valeurs soit setter par le provider. + * + * Test par indices. + * + * @throws Exception + */ + @Test + public void testReductionAndProvider() throws Exception { + MatrixND matrix = getTestProxy(7); + Assert.assertEquals(3, matrix.getDimCount()); + Assert.assertEquals(7, matrix.getDim(0)); + Assert.assertEquals("Cities", matrix.getDimensionName(1)); + + // toutes la matrice, mais juste pour les années 2002/2003 + MatrixND subMatrix = matrix.getSubMatrix(new int[][]{new int[]{2,3}, null, null}); + if (log.isDebugEnabled()) { + log.debug("subMatrix = " + subMatrix); + } + Assert.assertEquals(2, subMatrix.getDim(0)); + Assert.assertEquals(10.0, subMatrix.getValue(0, 0, 0), 0.0001); + } + + /** + * Test de manipuler la matrice comme une matrice normale + * et que ses valeurs soit setter par le provider. + * + * Test par objet de semantique. + * + * @throws Exception + */ + @Test + public void testReductionAndProviderObject() throws Exception { + MatrixND matrix = getTestProxy(7); + Assert.assertEquals(3, matrix.getDimCount()); + Assert.assertEquals(7, matrix.getDim(0)); + Assert.assertEquals("Cities", matrix.getDimensionName(1)); + + // toutes la matrice, mais juste pour les années 2002/2003 + MatrixND subMatrix = matrix.getSubMatrix(new Object[][]{new String[]{"2002","2003"}, null, null}); + Assert.assertEquals(2, subMatrix.getDim(0)); + Assert.assertEquals(10.0, subMatrix.getValue(0, 0, 0), 0.0001); + } + + +} Property changes on: trunk/nuiton-matrix/src/test/java/org/nuiton/math/matrix/MatrixProxyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL
participants (1)
-
echatellier@users.nuiton.org