r289 - in trunk/src: main/java/org/nuiton/math/matrix test/java/org/nuiton/math/matrix
Author: echatellier Date: 2010-11-25 10:20:22 +0100 (Thu, 25 Nov 2010) New Revision: 289 Url: http://nuiton.org/repositories/revision/nuiton-matrix/289 Log: #1093 : Add new function to reduce matrix with mean over dimension Modified: trunk/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java trunk/src/main/java/org/nuiton/math/matrix/MatrixND.java trunk/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java Modified: trunk/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java =================================================================== --- trunk/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java 2010-11-21 14:30:41 UTC (rev 288) +++ trunk/src/main/java/org/nuiton/math/matrix/AbstractMatrixND.java 2010-11-25 09:20:22 UTC (rev 289) @@ -666,8 +666,56 @@ return result; } + + @Override + public double meanAll() { + double sum = 0; + double number = 0; + for (MatrixIterator i = iterator(); i.next();) { + sum += i.getValue(); + number++; + } + double result = sum / number; + return result; + } @Override + public MatrixND meanOverDim(int dim) { + return meanOverDim(dim, getDim(dim)); + } + + @Override + public MatrixND meanOverDim(int dim, int step) { + if (step < 0) { + step = getDim(dim); + } else if (step <= 1) { + // il n'y a rien a faire, on fait une copie et on la retrourne + return getFactory().create(this); + } + + // le nombre d'element qu'il y aura dans la dim pour le resultat + int nbDim = getDim(dim) / step; + + List<?>[] semantics = new List<?>[getDimCount()]; + System.arraycopy(getSemantics(), 0, semantics, 0, getDimCount()); + semantics[dim] = semantics[dim].subList(0, nbDim); + + // creation du resultat + MatrixND result = getFactory().create(getName(), semantics, + getDimensionNames()); + + for (int i = 0; i < result.getDim(dim); i++) { + MatrixND temp = getSubMatrix(dim, i * step, step); + MatrixND sum = result.getSubMatrix(dim, i, 1); + for (int s = 0; s < temp.getDim(dim); s++) { + sum.add(temp.getSubMatrix(dim, s, 1)); + } + sum.divs(temp.getDim(dim)); // mean specifics + } + return result; + } + + @Override public MatrixND cut(int dim, int[] toCut) { throw new UnsupportedOperationException("Méthode non implantée"); } Modified: trunk/src/main/java/org/nuiton/math/matrix/MatrixND.java =================================================================== --- trunk/src/main/java/org/nuiton/math/matrix/MatrixND.java 2010-11-21 14:30:41 UTC (rev 288) +++ trunk/src/main/java/org/nuiton/math/matrix/MatrixND.java 2010-11-25 09:20:22 UTC (rev 289) @@ -440,8 +440,78 @@ public MatrixND sumOverDim(int dim, int step); public MatrixND sumOverDim(int dim, int start, int nb); + + /** + * Return all matrix data mean value + * + * @return mean value + */ + public double meanAll(); /** + * Effectue la moyenne des valeurs sur une dimension donnée. La matrice + * résultat à le même nombre de dimension, pas la dimension moyenisée, ne + * contient qu'une ligne. + * <p> + * par exemple pour la matrice suivante si on fait la moyenne sur la + * dimension 1 cela donnera + * + * <pre> + * 1 2 3 + * 8 9 4 + * 7 6 5 + * </pre> + * + * <pre> + * 5.33 4.66 4 + * </pre> + * + * @param dim la dimension sur lequel il faut faire la moyenne + * @return new matrix + */ + public MatrixND meanOverDim(int dim); + + /** + * Effectue la moyenne des valeurs sur une dimension donnée. la moyenne + * permet juste de regrouper dans une dimension un certain nombre de valeur. + * <p> + * pour la matrice suivante : + * + * <pre> + * 1 2 3 4 + * 2 3 4 5 + * 3 4 5 6 + * 4 5 6 7 + * </pre> + * + * la moyenne sur la dimension 1 avec un pas de 2 donnera : + * + * <pre> + * 1.5 3.5 4.5 4.5 + * 4.5 4.5 5.5 6.5 + * </pre> + * + * c'est à dire que sur la ligne 0 et la ligne 1 on fait la moyenne. ainsi + * que la ligne 2 avec la ligne 3. + * + * @param dim la dimension sur lequel il faut faire les sommes + * @param step le pas qu'il faut utiliser pour regrouper les elements. Si le + * pas est inférieur à 0, le pas se comporte comme si on avait + * passé en argument la taille de la dimension. Un pas de 0 ou 1, + * retourne juste une copie de la matrice actuelle. si la + * division du pas avec la taille de la dimension ne donne pas un + * nombre entier, les elements restants ne sont pas pris en + * compte. Par exemple si la dimension a 10 élements et que l'on + * donne un pas de 3, dans la matrice resultat la dimension aura + * 3 elements qui seront la somme par 3 des 9 premiers element de + * la matrice courante. Le 10eme element sera perdu. + * @return une nouvelle matrice avec le meme nombre de dimension mais dont + * la dimension passé en paramètre aura comme taille, le resultat de + * la division entier de la taille actuelle par le step + */ + public MatrixND meanOverDim(int dim, int step); + + /** * Permet de supprimer des éléments de la matrice. * Par exemple, pour la matrice * @@ -592,7 +662,7 @@ public MatrixND getSubMatrix(int dim, int[] elem); /** - * Addition la matrice courante avec la matrice passe en parametre et ce + * Addition la matrice courante avec la matrice passe en parametre et se * retourne elle meme. * * @param m matrix to add Modified: trunk/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java =================================================================== --- trunk/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java 2010-11-21 14:30:41 UTC (rev 288) +++ trunk/src/test/java/org/nuiton/math/matrix/MatrixNDTest.java 2010-11-25 09:20:22 UTC (rev 289) @@ -322,7 +322,114 @@ Assert.assertEquals(9, mat.getValue(5, 0, 3), 0); } + /** + * Test les fonctions meanOverDim... + * + * La matrice de test est + * 1 2 3 4 + * 5 6 7 8 + * 9 10 11 12 + * 13 14 15 16 + * @throws Exception + */ @Test + public void testMeanOverDim() throws Exception { + + // first test matrix : + // 1 2 3 4 + // 5 6 7 8 + // 9 10 11 12 + // 13 14 15 16 + + MatrixND mat = null; + mat = getFactory().create(new int[] { 4, 4 }); + MatrixND mat2 = mat; + int i = 0; + for (MatrixIterator mi = mat.iterator(); mi.next();) { + mi.setValue(++i); + } + + Assert.assertEquals(mat, mat2); + mat2 = mat.meanOverDim(1, 0); + Assert.assertEquals(mat, mat2); + mat2 = mat.meanOverDim(1, 1); + Assert.assertEquals(mat, mat2); + mat2 = mat.meanOverDim(1, 2); + Assert.assertEquals(2, mat2.getDim(1)); + Assert.assertEquals(1.5, mat2.getValue(0, 0), 0); + Assert.assertEquals(3.5, mat2.getValue(0, 1), 0); + Assert.assertEquals(5.5, mat2.getValue(1, 0), 0); + Assert.assertEquals(7.5, mat2.getValue(1, 1), 0); + Assert.assertEquals(9.5, mat2.getValue(2, 0), 0); + Assert.assertEquals(11.5, mat2.getValue(2, 1), 0); + Assert.assertEquals(13.5, mat2.getValue(3, 0), 0); + Assert.assertEquals(15.5, mat2.getValue(3, 1), 0); + + mat2 = mat.meanOverDim(1, 3); + Assert.assertEquals(1, mat2.getDim(1)); + Assert.assertEquals(2.0, mat2.getValue(0, 0), 0); + Assert.assertEquals(6.0, mat2.getValue(1, 0), 0); + Assert.assertEquals(10.0, mat2.getValue(2, 0), 0); + Assert.assertEquals(14.0, mat2.getValue(3, 0), 0); + + mat2 = mat.meanOverDim(1, 4); + Assert.assertEquals(1, mat2.getDim(1)); + Assert.assertEquals(2.5, mat2.getValue(0, 0), 0); + Assert.assertEquals(6.5, mat2.getValue(1, 0), 0); + Assert.assertEquals(10.5, mat2.getValue(2, 0), 0); + Assert.assertEquals(14.5, mat2.getValue(3, 0), 0); + + // meanAll + double meanAll = mat.meanAll(); + Assert.assertEquals(8.5, meanAll, 0); + + // seconde matrice (en 3 dimension :D) + // 2 3 3 3 3 3 3 3 3 + // 3 3 3 3 3 3 3 3 3 + // 3 3 3 3 3 3 3 3 4 + 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" }); + mat = getFactory().create("Ma mat", new List[] { s1, s2, s3 }, + new String[] { "dim abc", "dim efg", "dim klm" }); + + MatrixHelper.fill(mat, 3); + mat.setValue(0, 0, 0, 2); + mat.setValue(2, 2, 2, 4); + mat = mat.meanOverDim(1); + // donne : + // 2.66 3 3 3 3 3 3 3 3.33 + Assert.assertTrue(MatrixHelper.sameDimension(new int[] { 3, 1, 3 }, mat + .getDim())); + + Assert.assertEquals(2.6666, mat.getValue(0, 0, 0), 0.0001); + Assert.assertEquals(3, mat.getValue(2, 0, 1), 0); + Assert.assertEquals(3.3333, mat.getValue(2, 0, 2), 0.0001); + + mat = getFactory().create(new int[] { 6, 6, 6 }); + + MatrixHelper.fill(mat, 3); + mat.setValue(0, 0, 0, 0); + mat.setValue(0, 1, 0, 1); + mat.setValue(0, 2, 0, 2); + mat.setValue(0, 3, 0, 3); + mat.setValue(0, 4, 0, 4); + mat.setValue(0, 5, 0, 5); + + // meanAll + meanAll = mat.meanAll(); + Assert.assertEquals(2.9861, meanAll, 0.0001); + + mat = mat.meanOverDim(1, 3); + Assert.assertTrue(MatrixHelper.sameDimension(new int[] { 6, 2, 6 }, mat + .getDim())); + Assert.assertEquals(1.0, mat.getValue(0, 0, 0), 0); + Assert.assertEquals(4.0, mat.getValue(0, 1, 0), 0); + Assert.assertEquals(3.0, mat.getValue(1, 1, 5), 0); + Assert.assertEquals(3.0, mat.getValue(5, 0, 3), 0); + } + + @Test public void testTranspose() throws Exception { MatrixND mat = null;
participants (1)
-
echatellier@users.nuiton.org