diff --git a/README.md b/README.md index a4766887d5d14ef8fef172cd93e41ad2345d6c74..2d1b9c41923012afbfa630e7c4d6a442f1a20a56 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Numeric + + Ce repository contient l'énoncé du TP "numeric" et un squelette maven. Nous vous conseillons de vous abonner aux notifications (watch) pour ne pas manquer des annonces ou des changements. @@ -8,6 +10,98 @@ Après avoir choisi votre binôme, vous devrez **impérativement** : - Ajouter Joel Cavat (@joel.cavat), Jeremy Gobet (@jeremy.gobet) et Steven Liatti (@steven.liatti) en tant que *Reporter* de votre repository. - Lire attentivement l'énoncé. +## Fonctionnalités à réaliser sur les vecteurs (itération 1) + +Le projet contient déjà un ensemble de tests unitaires. Faites-en sorte que le projet compile et que les tests passsent. + +Vous devez réaliser des fonctionnalités sur les calculs vectoriels (dans un premier temps). Utilisez le package `ch.hepia.numeric` pour mettre vos classes. + +### Opérations sur les vecteurs (méthodes d'instance) + +(Regardez les tests unitaires pour comprendre comment elles fonctionnent) + +- [ ] `add(), mul(), sub()` pour les opérations de bases +- [ ] `norm()` pour calculer la norme d'un vecteur +- [ ] `t()` pour retourner la vesion transposée +- [ ] `dot()` pour retourner le produit scalaire de deux vecteurs (en notation matricielle) +- [ ] `get()` pour retourner un élément (le premier élément se trouve en position 0) +- [ ] `set()` en tant que méthode non publique pour modifier une valeur +- [ ] `map()` pour retourner une version transformée +- [ ] `concat()` pour concatener deux vecteurs +- [ ] `copy()` pour copier un vecteur +- [ ] `slice(), sliceTo(), sliceFrom()` pour les opérations de slicing +- [ ] `removed()` pour retourner une sans un des éléments +- [ ] `toString()` et `equals()` pour une représentation et la comparaison de vecteur +- [ ] Toutes ces fonctionnalités doivent exister sur un **vecteur transposé**. +- [ ] Retourne RuntimeException() avec un message approprié en cas d'erreurs + +##### Vecteur + +```math +\vec{x} = \begin{bmatrix} + x_1 \\ x_2 \\ ... \\ x_n +\end{bmatrix} +``` + + +##### Transposée + +```math +\vec{x}^t = \begin{bmatrix} + x_1 & x_2 & ... & x_n +\end{bmatrix} +``` + +##### Produit scalaire en notation matricielle + +```math +\vec{x}^t \cdot \vec{y} = \begin{bmatrix} + x_1 & x_2 & ... & x_n +\end{bmatrix} \cdot \begin{bmatrix} + y_1 \\ y_2 \\ ... \\ y_n +\end{bmatrix} = \sum_{i=1}^n x_i \cdot y_i +``` + +##### Norme d'un vecteur + +```math +\vec{v} \begin{pmatrix} + v_1 \\ + v_2 \\ + ... \\ + v_n +\end{pmatrix} = \lVert \vec{v} \rVert = \sqrt{v_1^2 + v_2^2 + ... + v_n^2} +``` + +##### Map + +```math +map(\vec{x}, f) = \begin{bmatrix} + f(x_1) \\ f(x_2) \\ ... \\ f(x_n) +\end{bmatrix} +``` + +### Opérations statiques (méthodes de classes) + +(Regardez les tests unitaires pour comprendre comment elles fonctionnent) + +- [ ] `of()` +- [ ] `empty()` +- [ ] `fill()` +- [ ] `zeros()` +- [ ] `ones()` +- [ ] `linespace()` +- [ ] `tabulate()` +- [ ] `sum()` +- [ ] `norms()` + +### Remarques + +Les constructeurs doivent être non publiques. Pour créer un élément, vous devez utilisez une fabrique (méthode statique) tel que `of()` ou `empty()` + +## Fonctionnalités à réaliser sur les matrices (prochaine itération) + +TBD # Maven @@ -29,7 +123,7 @@ mvn package java -cp target/my-app-0.1.jar ch.hepia.my_app.App ``` -- ou, à l'aide du plugin `exec-maven-plugin`: +- ou, à l'aide du plugin `exec-maven-plugin` (plus simple): ``` mvn exec:java diff --git a/src/main/java/ch/hepia/my_app/App.java b/src/main/java/ch/hepia/App.java similarity index 85% rename from src/main/java/ch/hepia/my_app/App.java rename to src/main/java/ch/hepia/App.java index 438990991a9c116a303f71501217cfedf23ccbb5..c6a365b6f3b39d15b0e091caae5b45c34ae9b214 100644 --- a/src/main/java/ch/hepia/my_app/App.java +++ b/src/main/java/ch/hepia/App.java @@ -1,4 +1,4 @@ -package ch.hepia.my_app; +package ch.hepia; /** * Hello world! diff --git a/src/main/java/ch/hepia/numeric/Vector.java b/src/main/java/ch/hepia/numeric/Vector.java new file mode 100644 index 0000000000000000000000000000000000000000..d210742e36bae5513ad8ee5176c15633db40a1c8 --- /dev/null +++ b/src/main/java/ch/hepia/numeric/Vector.java @@ -0,0 +1,129 @@ +package ch.hepia.numeric; + +import java.util.List; +import java.util.function.DoubleFunction; +import java.util.function.Function; + +final public class Vector { + private Vector() {} + private Vector(Double... elements) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + private Vector(List<Double> elements) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Transposed t() { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public int len() { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public double get(int i) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + void set(int i, double value) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector add(Vector that) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector mul(double m) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector sub(Vector that) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public double norm() { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector sliceFrom(int i) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector sliceTo(int i) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector slice(int from, int to) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector removed(int i) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector concat(Vector that) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector map(DoubleFunction<Double> f) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public Vector copy() { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + void checkVectorLengthOrThrow(Vector that){ + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector of(Double... elements) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector of(List<Double> elements) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector empty() { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector fill(int nb, double value) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector zeros(int nb) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector ones(int nb) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector linespace(double from, double to, int nb) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector tabulate(int nb, Function<Integer, Double> f) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static Vector sum(List<Vector> vs) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + public static double norms(List<Vector> vs) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + + @Override + public String toString() { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } + + @Override + public boolean equals(Object obj) { + throw new UnsupportedOperationException("This feature isn't implemented yet"); + } +} diff --git a/src/test/java/ch/hepia/my_app/AppTest.java b/src/test/java/ch/hepia/my_app/AppTest.java deleted file mode 100644 index 11494066e0985a78203deba5c5cb3fcf29ae028d..0000000000000000000000000000000000000000 --- a/src/test/java/ch/hepia/my_app/AppTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package ch.hepia.my_app; - -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertFalse; - - -/** - * Unit test for simple App. - */ -class AppTest { - - @Test - void dummyTest() { - assertTrue(true); - } -} diff --git a/src/test/java/ch/hepia/numeric/AppTest.java b/src/test/java/ch/hepia/numeric/AppTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a3c1134fcaedeb0659877d25c0912734fdc79a11 --- /dev/null +++ b/src/test/java/ch/hepia/numeric/AppTest.java @@ -0,0 +1,84 @@ +package ch.hepia.numeric; + +import org.junit.jupiter.api.Test; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + + +class VectorTest { + + @Test + void vectorMainOperations() { + Vector v1 = Vector.of(1.0, 2.0, 3.0); + Vector v2 = Vector.of(-1.0, -2.0, -3.0); + assertEquals(v1.add(v2), Vector.of(0.0, 0.0, 0.0)); + assertEquals(v1.sub(v2), Vector.of(2.0, 4.0, 6.0)); + assertEquals(v1.mul(3.0), Vector.of(3.0, 6.0, 9.0)); + assertEquals(Vector.empty().len(), 0); + assertEquals(Vector.of(1.0, 2.0, 1.0).len(), 3); + } + @Test + void vectorCreation() { + assertEquals(Vector.zeros(3), Vector.of(0.0, 0.0, 0.0)); + assertEquals(Vector.ones(3), Vector.of(1.0, 1.0, 1.0)); + assertEquals(Vector.of(1.0, 2.0).map( d -> d * 2.0), Vector.of(2.0, 4.0)); + assertEquals(Vector.fill(3, 1.7), Vector.of(1.7, 1.7, 1.7)); + assertEquals(Vector.tabulate(4, i -> i*5.0), Vector.of(0.0, 5.0, 10.0, 15.0)); + } + @Test + void vectorLinespace() { + assertEquals(Vector.linespace(0.0, 1.0, 3), Vector.of(0.0, 0.5, 1.0)); + assertEquals(Vector.linespace(0.0, 1.0, 5), Vector.of(0.0, 0.25, 0.5, 0.75, 1.0)); + } + @Test + void vectorNormAndSum() { + assertEquals(Vector.of(1.0, 2.0, 2.0).norm(), 3.0); + assertEquals(Vector.sum(List.of(Vector.of(1.0, 2.0, 1.0), Vector.of(0.0, 0.0, 1.0))).norm(), 3.0); + assertEquals( + Vector.sum(List.of(Vector.of(1.0, 2.0, 1.0), Vector.of(0.0, 0.0, 1.0))).norm(), + Vector.norms(List.of(Vector.of(1.0, 2.0, 1.0), Vector.of(0.0, 0.0, 1.0))) + ); + assertEquals(Vector.sum(List.of(Vector.of(1.0, 2.0, 1.0), Vector.of(0.0, 0.0, 1.0))), Vector.of(1.0, 2.0, 2.0)); + } + @Test + void vectorTranspose() { + Vector v1 = Vector.of(1.0, 2.0, 3.0); + Vector v2 = Vector.of(1.0, 0.0, -1.0); + assertEquals(v1.t().dot(v2), -2.0); + /* + * v1.dot(v2) should not compile !!! + * only a transposed vector with a vector + */ + Vector v3 = Vector.of(1.0, 2.0, 3.0); + Vector v4 = Vector.of(1.0, 2.0, 3.0); + assertEquals( v3.t().dot(v4), 14.0 ); + assertEquals( v3.t().sub(v4.t()), Vector.of(0.0, 0.0, 0.0).t() ); + } + + @Test + void vectorToString() { + Vector v = Vector.of(1.0, 2.0, 3.0); + assertEquals(v.toString(), "Vector[1.0, 2.0, 3.0]"); + assertEquals(v.t().toString(), "Transposed[1.0, 2.0, 3.0]"); + } + + @Test + void vectorSlice() { + Vector v = Vector.of(1.0, 2.0, 3.0, 4.0, 5.0); + assertEquals(v.sliceFrom(2), Vector.of(3.0, 4.0, 5.0)); + assertEquals(v.sliceTo(3), Vector.of(1.0, 2.0, 3.0)); + assertEquals(v.slice(2,4), Vector.of(3.0, 4.0)); + assertEquals(v.slice(4,4), Vector.empty()); + assertEquals(v.slice(4,2), Vector.empty()); + assertEquals(v.removed(2), Vector.of(1.0, 2.0, 4.0, 5.0)); + } + @Test + void vectorConcat() { + Vector v1 = Vector.of(1.0, 2.0, 3.0); + Vector v2 = Vector.of(-1.0, -2.0, -3.0); + assertEquals(v1.concat(v2), Vector.of(1.0, 2.0, 3.0, -1.0, -2.0, -3.0)); + } +}