- import of splitter-NG SVN repository from : https://obelinux.inf.tu-dresden.de...
authorJosef Spillner <josef.spillner@tu-dresden.de>
Thu, 22 May 2014 11:15:48 +0000 (13:15 +0200)
committerJosef Spillner <josef.spillner@tu-dresden.de>
Thu, 22 May 2014 11:15:48 +0000 (13:15 +0200)
273 files changed:
Splitter-ng-plugin-JSharing/.classpath [new file with mode: 0644]
Splitter-ng-plugin-JSharing/.directory [new file with mode: 0644]
Splitter-ng-plugin-JSharing/.project [new file with mode: 0644]
Splitter-ng-plugin-JSharing/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
Splitter-ng-plugin-JSharing/build.xml [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/.directory [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/AbsOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/AddOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/AffineLinearSubspace.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/AndOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/BinaryFloat.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/Complex.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/DiagonalMatrix.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/DivideOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/DivisionByZeroException.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/DoubleWrapper.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/DyadicOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/EqualToComparator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/F2.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/FEComparator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/FieldElement.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/FieldP.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/GreaterThanComparator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/GreaterThanOrEqualToComparator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/Handbook.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/InvalidOperationException.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/LessThanComparator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/LessThanOrEqualToComparator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/LinAlgFactory.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/LinSysSolver.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/LinearSubspace.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/Matrix.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/MatrixMultiplication.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/MaxReduction.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/MinReduction.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/MonadicOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/MultiplyOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/NotEqualToComparator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/NotOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/OrOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/Rational.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/Reduction.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/SubtractOperator.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/SumReduction.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JLinAlg/Vector.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JSharing/blakley/blakley.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JSharing/shamir/shamir.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JSharing/shamir/shamirException.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/JSharing/shamir/shamirKey.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/ShamirCodec.java [new file with mode: 0644]
Splitter-ng-plugin-JSharing/src/SplitterPluginJSharing.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/.classpath [new file with mode: 0644]
Splitter-ng-plugin-jerasure/.directory [new file with mode: 0644]
Splitter-ng-plugin-jerasure/.project [new file with mode: 0644]
Splitter-ng-plugin-jerasure/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/.gitignore [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/Makefile [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/cauchy_01.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/cauchy_02.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/cauchy_03.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/cauchy_04.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/decoder.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/encoder.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_01.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_02.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_03.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_04.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_05.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_06.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_07.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/jerasure_08.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/liberation_01.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/reed_sol_01.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/reed_sol_02.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/reed_sol_03.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Examples/reed_sol_04.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/License.txt [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/Makefile [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/README.md [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/README.txt [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/CS-08-627.pdf [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/bc_s.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/cauchy_8c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/cauchy_8h.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/cauchy_8h_source.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/cauchy__best__r6_8c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/closed.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/doxygen.css [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/doxygen.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/files.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/form_0.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/form_1.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/form_2.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/form_3.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/form_4.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/formula.repository [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/galois_8c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/galois_8h.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/galois_8h_source.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/globals.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/globals_defs.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/globals_func.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/globals_vars.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/index.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/installdox [new file with mode: 0755]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/jerasure_8c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/jerasure_8h.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/jerasure_8h_source.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/jquery.js [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/liberation_8c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/liberation_8h.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/liberation_8h_source.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/nav_f.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/nav_h.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/open.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/pages.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/reed__sol_8c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/reed__sol_8h.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/reed__sol_8h_source.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_62.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_63.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_67.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_6a.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_6c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_6e.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_72.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_73.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/all_74.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/close.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/defines_6c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/defines_6e.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/defines_72.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/defines_73.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/defines_74.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/files_63.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/files_67.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/files_6a.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/files_6c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/files_72.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/functions_62.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/functions_63.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/functions_67.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/functions_6a.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/functions_6c.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/functions_72.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/mag_sel.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/nomatches.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/search.css [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/search.js [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/search_l.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/search_m.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/search_r.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/search/variables_63.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/tab_a.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/tab_b.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/tab_h.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/tab_s.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/tabs.css [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/html/todo.html [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/Makefile [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/cauchy_8c.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/cauchy_8h.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/cauchy__best__r6_8c.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/doxygen.sty [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/files.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/galois_8c.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/galois_8h.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/jerasure_8c.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/jerasure_8h.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/liberation_8c.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/liberation_8h.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/reed__sol_8c.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/reed__sol_8h.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/refman.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doc/latex/todo.tex [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/doxygen.config [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/.gitignore [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/jerasure-jni-binding.iml [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/src/META-INF/MANIFEST.MF [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/src/eu/vandertil/jerasure/LibraryLoader.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/src/eu/vandertil/jerasure/jni/Cauchy.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/src/eu/vandertil/jerasure/jni/Galois.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/src/eu/vandertil/jerasure/jni/Jerasure.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/src/eu/vandertil/jerasure/jni/Liberation.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/java/src/eu/vandertil/jerasure/jni/ReedSolomon.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JCauchy.cpp [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JCauchy.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JGalois.cpp [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JGalois.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JJerasure.cpp [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JJerasure.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JLiberation.cpp [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JLiberation.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JReedSolomon.cpp [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/JReedSolomon.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/Makefile [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/javautility.cpp [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/jni/javautility.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/Makefile [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/cauchy.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/cauchy.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/cauchy_best_r6.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/galois.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/galois.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/jerasure.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/jerasure.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/liberation.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/liberation.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/reed_sol.c [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/src/reed_sol.h [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/win32/.gitignore [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/win32/Jerasure.JNI/Jerasure.JNI.vcxproj [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/win32/Jerasure.JNI/Jerasure.JNI.vcxproj.filters [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/win32/Jerasure.Library/Jerasure.Library.vcxproj [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/win32/Jerasure.Library/Jerasure.Library.vcxproj.filters [new file with mode: 0644]
Splitter-ng-plugin-jerasure/Jerasure-1.2-java/win32/Jerasure.sln [new file with mode: 0644]
Splitter-ng-plugin-jerasure/build.xml [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/cz/adamh/utils/NativeUtils.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/eu/vandertil/jerasure/LibraryLoader.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/eu/vandertil/jerasure/jni/Cauchy.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/eu/vandertil/jerasure/jni/Galois.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/eu/vandertil/jerasure/jni/Jerasure.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/eu/vandertil/jerasure/jni/Liberation.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/eu/vandertil/jerasure/jni/ReedSolomon.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/CodecBlaumRoth.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/CodecCauchyGood.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/CodecCauchyOrg.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/CodecLiber8tion.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/CodecLiberation.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/CodecReedSolomonRaid6.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/CodecReedSolomonVandermonde.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/src/jerasureplugin/JerasurePlugin.java [new file with mode: 0644]
Splitter-ng-plugin-jerasure/uml/uml.png [new file with mode: 0644]
Splitter-ng-plugin-jerasure/uml/uml.ucls [new file with mode: 0644]
Splitter-ng-plugin-raid1/.classpath [new file with mode: 0644]
Splitter-ng-plugin-raid1/.project [new file with mode: 0644]
Splitter-ng-plugin-raid1/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
Splitter-ng-plugin-raid1/build.xml [new file with mode: 0644]
Splitter-ng-plugin-raid1/src/CodecRaid1.java [new file with mode: 0644]
Splitter-ng-plugin-raid1/src/SplitterPluginRaid1.java [new file with mode: 0644]
Splitter-ng-test/.classpath [new file with mode: 0644]
Splitter-ng-test/.project [new file with mode: 0644]
Splitter-ng-test/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
Splitter-ng-test/build.xml [new file with mode: 0644]
Splitter-ng-test/src/SplitterTest.java [new file with mode: 0644]
Splitter-ng-test/srcDir/test-abcd [new file with mode: 0644]
Splitter-ng-test/srcDir/test-text [new file with mode: 0644]
Splitter-ng-test/starttest [new file with mode: 0755]
Splitter-ng-test/starttest-x [new file with mode: 0755]
Splitter-ng/.classpath [new file with mode: 0644]
Splitter-ng/.directory [new file with mode: 0644]
Splitter-ng/.project [new file with mode: 0644]
Splitter-ng/build.xml [new file with mode: 0644]
Splitter-ng/src/splitterng/CodingTask.java [new file with mode: 0644]
Splitter-ng/src/splitterng/DecodingTask.java [new file with mode: 0644]
Splitter-ng/src/splitterng/EncodingTask.java [new file with mode: 0644]
Splitter-ng/src/splitterng/Splitter.java [new file with mode: 0644]
Splitter-ng/src/splitterng/SplitterCallback.java [new file with mode: 0644]
Splitter-ng/src/splitterng/SplitterConfiguration.java [new file with mode: 0644]
Splitter-ng/src/splitterng/SplitterWorker.java [new file with mode: 0644]
Splitter-ng/src/splitterng/Statistics.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/CodecDescription.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/JARFileFilter.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/PluginDescription.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/PluginLoader.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/PluginManagerImpl.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/interfaces/Plugable.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/interfaces/PluginManager.java [new file with mode: 0644]
Splitter-ng/src/splitterng/plugin/interfaces/SplitterCodec.java [new file with mode: 0644]
Splitter-ng/uml/KlassenCodingTask.png [new file with mode: 0644]
Splitter-ng/uml/KlassenCodingTask.ucls [new file with mode: 0644]
Splitter-ng/uml/PluginFactory.ucls [new file with mode: 0644]
build.xml [new file with mode: 0644]

diff --git a/Splitter-ng-plugin-JSharing/.classpath b/Splitter-ng-plugin-JSharing/.classpath
new file mode 100644 (file)
index 0000000..b252a08
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+       <classpathentry combineaccessrules="false" exported="true" kind="src" path="/Splitter-ng"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/Splitter-ng-plugin-JSharing/.directory b/Splitter-ng-plugin-JSharing/.directory
new file mode 100644 (file)
index 0000000..1712f09
--- /dev/null
@@ -0,0 +1,9 @@
+[Dolphin]
+SortRole=orientation
+Timestamp=2013,11,7,18,6,2
+Version=3
+ViewMode=1
+VisibleRoles=Details_text,Details_size,Details_date,Details_type,CustomizedDetails
+
+[Settings]
+HiddenFilesShown=true
diff --git a/Splitter-ng-plugin-JSharing/.project b/Splitter-ng-plugin-JSharing/.project
new file mode 100644 (file)
index 0000000..f5c5779
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>Splitter-ng-plugin-JSharing</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/Splitter-ng-plugin-JSharing/.settings/org.eclipse.jdt.core.prefs b/Splitter-ng-plugin-JSharing/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..7341ab1
--- /dev/null
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/Splitter-ng-plugin-JSharing/build.xml b/Splitter-ng-plugin-JSharing/build.xml
new file mode 100644 (file)
index 0000000..ec2b235
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project basedir="." default="makejar" name="Splitter-ng-plugin-JSharing">
+       <property environment="env" />
+       <property name="Splitter-ng.location" value="../Splitter-ng" />
+       <property name="debuglevel" value="source,lines,vars" />
+       <property name="target" value="1.7" />
+       <property name="source" value="1.7" />
+       <path id="Splitter-ng.classpath">
+               <pathelement location="${Splitter-ng.location}/bin" />
+       </path>
+       <path id="Splitter-ng-plugin-JSharing.classpath">
+               <pathelement location="bin" />
+               <path refid="Splitter-ng.classpath" />
+       </path>
+       <target name="init">
+               <mkdir dir="bin" />
+               <copy includeemptydirs="false" todir="bin">
+                       <fileset dir="src">
+                               <exclude name="**/*.uad" />
+                               <exclude name="**/*.ucd" />
+                               <exclude name="**/*.uld" />
+                               <exclude name="**/*.upd" />
+                               <exclude name="**/*.udd" />
+                               <exclude name="**/*.uod" />
+                               <exclude name="**/*.usd" />
+                               <exclude name="**/*.utd" />
+                               <exclude name="**/*.uud" />
+                               <exclude name="**/*.odd" />
+                               <exclude name="**/*.ead" />
+                               <exclude name="**/*.ecd" />
+                               <exclude name="**/*.eld" />
+                               <exclude name="**/*.epd" />
+                               <exclude name="**/*.edd" />
+                               <exclude name="**/*.eod" />
+                               <exclude name="**/*.esd" />
+                               <exclude name="**/*.etd" />
+                               <exclude name="**/*.eud" />
+                               <exclude name="**/*.urd" />
+                               <exclude name="**/*.uml" />
+                               <exclude name="**/*.ecore" />
+                               <exclude name="**/*.ucls" />
+                               <exclude name="**/*.useq" />
+                               <exclude name="**/*.java" />
+                       </fileset>
+               </copy>
+       </target>
+       <target name="clean">
+               <delete dir="bin" />
+       </target>
+       <target depends="clean" name="cleanall">
+               <ant antfile="build.xml" dir="${Splitter-ng.location}" inheritAll="false" target="clean" />
+       </target>
+       <target depends="build-subprojects,build-project" name="build" />
+       <target name="build-subprojects">
+               <ant antfile="build.xml" dir="${Splitter-ng.location}" inheritAll="false" target="build-project" />
+       </target>
+       <target depends="init" name="build-project">
+               <echo message="${ant.project.name}: ${ant.file}" />
+               <javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
+                       <src path="src" />
+                       <classpath refid="Splitter-ng-plugin-JSharing.classpath" />
+               </javac>
+       </target>
+       <target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects" />
+
+       <target name="makejar" depends="build" description="Create a jar for the project">
+               <jar jarfile="bin/${ant.project.name}.jar">
+                       <fileset dir="bin" includes="**/*.class" />
+               </jar>
+       </target>
+       <target name="dist" depends="makejar" description="Create a distribution Directory wirth splitter-ng and all Plugins">
+               <mkdir dir="../dist" />
+               <mkdir dir="../dist/plugin" />
+               <copy file="bin/${ant.project.name}.jar" todir="../dist/plugin/" />
+       </target>
+</project>
diff --git a/Splitter-ng-plugin-JSharing/src/.directory b/Splitter-ng-plugin-JSharing/src/.directory
new file mode 100644 (file)
index 0000000..b5b3950
--- /dev/null
@@ -0,0 +1,9 @@
+[Dolphin]
+SortRole=orientation
+Timestamp=2013,11,7,18,6,59
+Version=3
+ViewMode=1
+VisibleRoles=Details_text,Details_size,Details_date,Details_type,CustomizedDetails
+
+[Settings]
+HiddenFilesShown=true
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/AbsOperator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/AbsOperator.java
new file mode 100644 (file)
index 0000000..876a99e
--- /dev/null
@@ -0,0 +1,12 @@
+package JLinAlg;
+
+
+
+// absolute value computation for FieldElement
+class AbsOperator implements MonadicOperator {
+
+    public FieldElement apply(FieldElement x) {
+       return x.lt(x.zero()) ? x.zero().subtract(x) : x;
+    }
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/AddOperator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/AddOperator.java
new file mode 100644 (file)
index 0000000..9b9815a
--- /dev/null
@@ -0,0 +1,12 @@
+package JLinAlg;
+
+
+
+// sum of two FieldElements
+class AddOperator implements DyadicOperator {
+
+       public FieldElement apply(FieldElement x, FieldElement y) {
+               return x.add(y);
+       }
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/AffineLinearSubspace.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/AffineLinearSubspace.java
new file mode 100644 (file)
index 0000000..ec13475
--- /dev/null
@@ -0,0 +1,192 @@
+package JLinAlg;\r
+\r
+import java.io.Serializable;\r
+import java.util.LinkedList;\r
+\r
+/**\r
+ * This class represents an affin linear subspace.\r
+ * \r
+ * @author Andreas Keilhauer\r
+ */\r
+\r
+@SuppressWarnings("serial")\r
+public class AffineLinearSubspace implements Serializable {\r
+\r
+       protected Vector inhomogenousPart = null;\r
+\r
+       protected Vector[] generatingSystem = null;\r
+\r
+       protected int dimension = -1;\r
+\r
+       protected boolean normalized = false;\r
+\r
+       /**\r
+        * This creates an affin linear subspace by taking an inhomogenous part and\r
+        * a generating System of Vectors. The subspace will be inhomogenousPart + <\r
+        * generatingSystem >.\r
+        * \r
+        * @param inhomogenousPart\r
+        * @param generatingSystem\r
+        */\r
+\r
+       public AffineLinearSubspace(Vector inhomogenousPart,\r
+                       Vector[] generatingSystem) throws InvalidOperationException {\r
+\r
+               if (generatingSystem != null && generatingSystem.length > 0) {\r
+                       this.generatingSystem = generatingSystem;\r
+               } else {\r
+                       this.generatingSystem = new Vector[0];\r
+               }\r
+\r
+               if (inhomogenousPart == null) {\r
+                       Vector tmp = generatingSystem[0];\r
+                       Vector zeroVector = new Vector(tmp.length());\r
+                       FieldElement zero = tmp.getEntry(1).zero();\r
+                       for (int i = 1; i <= zeroVector.length(); i++) {\r
+                               zeroVector.set(i, zero);\r
+                       }\r
+                       this.inhomogenousPart = zeroVector;\r
+               } else {\r
+                       this.inhomogenousPart = inhomogenousPart;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * This creates an affin linear subspace by taking an inhomogenous part and\r
+        * a generating System of Vectors. The subspace will be inhomogenousPart + <\r
+        * generatingSystem >. The normalized flag, which is usually set after\r
+        * normalize is executed, is also set, but it won't be checked.\r
+        * \r
+        * @param inhomogenousPart\r
+        * @param generatingSystem\r
+        * @param normalized\r
+        */\r
+\r
+       public AffineLinearSubspace(Vector inhomogenousPart,\r
+                       Vector[] generatingSystem, boolean normalized)\r
+                       throws InvalidOperationException {\r
+\r
+               this.normalized = true;\r
+\r
+               if (generatingSystem != null && generatingSystem.length > 0) {\r
+                       this.generatingSystem = generatingSystem;\r
+                       if (normalized) {\r
+                               this.dimension = generatingSystem.length;\r
+                       }\r
+               } else {\r
+                       this.generatingSystem = new Vector[0];\r
+               }\r
+\r
+               if (inhomogenousPart == null) {\r
+                       Vector tmp = generatingSystem[0];\r
+                       Vector zeroVector = new Vector(tmp.length());\r
+                       FieldElement zero = tmp.getEntry(1).zero();\r
+                       for (int i = 1; i <= zeroVector.length(); i++) {\r
+                               zeroVector.set(i, zero);\r
+                       }\r
+                       this.inhomogenousPart = zeroVector;\r
+               } else {\r
+                       this.inhomogenousPart = inhomogenousPart;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Gets the dimension of the affin linear subspace.\r
+        * \r
+        * @return dimension (number of independent Vectors of the generating\r
+        *         system).\r
+        */\r
+\r
+       public int getDimension() {\r
+               if (this.normalized) {\r
+                       return this.dimension;\r
+               } else {\r
+                       return (new Matrix(generatingSystem).rank());\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Gets the inhomogenous part of this affin linear vector space.\r
+        * \r
+        * @return inhomogenous part\r
+        */\r
+\r
+       public Vector getInhomogenousPart() {\r
+               return inhomogenousPart;\r
+       }\r
+\r
+       /**\r
+        * Gets the generating system of this affin linear vector space.\r
+        * \r
+        * @return generating system\r
+        */\r
+\r
+       public Vector[] getGeneratingSystem() {\r
+               return generatingSystem;\r
+       }\r
+\r
+       /**\r
+        * Returns a String representation of this affine linear subspace\r
+        * \r
+        * @return String representation\r
+        */\r
+\r
+       public String toString() {\r
+               String tmp = this.inhomogenousPart + " + < { ";\r
+               for (int i = 0; i < this.generatingSystem.length - 1; i++) {\r
+                       tmp += this.generatingSystem[i].toString() + ", ";\r
+               }\r
+               if (this.generatingSystem.length > 0) {\r
+                       tmp += this.generatingSystem[this.generatingSystem.length - 1];\r
+               }\r
+               return tmp + " } >";\r
+       }\r
+\r
+       /**\r
+        * This method calculates the normalized version of this AffineLinearSubspace.\r
+        * I.e. it eliminates all dependent vectors from the generating System.\r
+        * In a 1-dimensional AffineLinearSubspace it is also possible,\r
+        * that the inhomogenous part is dependent to the generating vector and\r
+        * therefore the inhomogenous can be dropped.\r
+        * \r
+        * @return the normalized version of this\r
+        */\r
+       public AffineLinearSubspace normalize() {\r
+               if (this.generatingSystem.length > 0) {\r
+                       Matrix normalized = new Matrix(generatingSystem).gausselim();\r
+                       LinkedList generatingVectors = new LinkedList();\r
+                       int i = 1;\r
+                       while (i < normalized.getRows() && !normalized.isZeroRow(i)) {\r
+                               generatingVectors.addLast(normalized.getRow(i));\r
+                               i++;\r
+                       }\r
+                       Vector[] newGeneratingSystem = (Vector[]) generatingVectors\r
+                                       .toArray(new Vector[0]);\r
+                       \r
+                       if(newGeneratingSystem.length == 1){\r
+                               Matrix testInhomogenousPart = new Matrix(new Vector[]{newGeneratingSystem[0], this.inhomogenousPart});\r
+                               if(testInhomogenousPart.rank() != 2){\r
+                                       return new LinearSubspace(newGeneratingSystem);\r
+                               }\r
+                       }\r
+                       if (this instanceof LinearSubspace) {\r
+                               return new LinearSubspace(newGeneratingSystem, true);\r
+                       } else {\r
+                               return new AffineLinearSubspace(this.inhomogenousPart,\r
+                                               newGeneratingSystem, true);\r
+                       }\r
+\r
+               }\r
+               \r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the value of the normalized flag\r
+        */\r
+       public boolean isNormalized() {\r
+               return this.normalized;\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/AndOperator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/AndOperator.java
new file mode 100644 (file)
index 0000000..e6d73b6
--- /dev/null
@@ -0,0 +1,11 @@
+package JLinAlg;
+
+
+
+// logical AND of two FieldElements
+class AndOperator implements DyadicOperator {
+
+       public FieldElement apply(FieldElement x, FieldElement y) {
+               return (x.isZero() || y.isZero()) ? x.zero() : x.one();
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/BinaryFloat.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/BinaryFloat.java
new file mode 100644 (file)
index 0000000..25cc6a6
--- /dev/null
@@ -0,0 +1,456 @@
+package JLinAlg;\r
+\r
+import java.math.BigInteger;\r
+\r
+/**\r
+ * An immutable arbitrary precision binary float. Internally it is stored as two\r
+ * BigIntegers, an exponent and a mantissa. The number represented is\r
+ * <code>mantissa * (2 ** exponent)</code>. The rightmost zeroes in the\r
+ * mantissa are removed after all operations, with the exponent updated\r
+ * accordingly. The length of the exponent is arbitrary. The leng of the\r
+ * mantissa is specified in the field "mantissa_length", which defaults to 0x80.\r
+ * Changing this length will only effect future operations.\r
+ * \r
+ * @author Ryan Keppel\r
+ */\r
+\r
+public class BinaryFloat extends FieldElement {\r
+\r
+       private final BigInteger mantissa;\r
+\r
+       private final BigInteger exponent;\r
+\r
+       public static int mantissa_length = 0x80;\r
+\r
+       public FieldElement negate() {\r
+               return new BinaryFloat(this.mantissa.negate(), this.exponent);\r
+       }\r
+\r
+       public FieldElement instance(double d) {\r
+               return new BinaryFloat(d);\r
+       }\r
+\r
+       public FieldElement invert() throws DivisionByZeroException{\r
+               if(this.isZero()){\r
+                       throw new DivisionByZeroException("Tried to invert zero.");\r
+               }\r
+               return new BinaryFloat(BigInteger.ONE).divide(this);\r
+       }\r
+\r
+       /**\r
+        * Returns the zero element for this field.\r
+        * \r
+        * @return zero\r
+        */\r
+\r
+       public FieldElement zero() {\r
+               return new BinaryFloat(BigInteger.ZERO);\r
+       }\r
+\r
+       /**\r
+        * Returns the one element for this field.\r
+        * \r
+        * @return one\r
+        */\r
+\r
+       public FieldElement one() {\r
+               return new BinaryFloat(BigInteger.ONE);\r
+       }\r
+\r
+       /**\r
+        * Implements Comparable.compareTo(Object).\r
+        * \r
+        * @param o\r
+        *            the object\r
+        * @return {-,+,0} as this object is less than, equal to, or greater than\r
+        *         the specified object.\r
+        */\r
+\r
+       public int compareTo(Object o) {\r
+               return compareTo((BinaryFloat) o);\r
+       }\r
+\r
+       private BigInteger shiftRight(BigInteger b, int i) {\r
+               BigInteger rt = b.abs().shiftRight(i);\r
+               if (b.signum() == -1)\r
+                       rt = rt.negate();\r
+               return rt;\r
+       }\r
+\r
+       private BigInteger shiftLeft(BigInteger b, int i) {\r
+               BigInteger rt = b.abs().shiftLeft(i);\r
+               if (b.signum() == -1)\r
+                       rt = rt.negate();\r
+               return rt;\r
+       }\r
+\r
+       private static int bigToInt(BigInteger b) {\r
+               if (b.bitLength() > 0x1F)\r
+                       throw new Error();\r
+               return b.intValue();\r
+       }\r
+\r
+       private BigInteger invRemainder(BigInteger b1, BigInteger b2) {\r
+               BigInteger b;\r
+               b = b1.remainder(b2);\r
+               if (b.signum() == 0)\r
+                       return b;\r
+               else\r
+                       return b2.subtract(b);\r
+       }\r
+\r
+       /*\r
+        * public BinaryFloat(BigInteger mantissa, BigInteger exponent) Hexadecimal\r
+        * constructor { this.mantissa=mantissa; exponent=exponent.multiply(new\r
+        * BigInteger("4")); exponent=exponent.subtract(invRemainder(\r
+        * BigInteger.valueOf(mantissa.abs().bitLength()),new BigInteger("4")) );\r
+        * this.exponent=exponent; normal(); }\r
+        */\r
+       /**\r
+        * Creates with double.\r
+        */\r
+       public BinaryFloat(double d) {\r
+               long a;\r
+               BigInteger man, exp;\r
+               BinaryFloat rt;\r
+               a = Double.doubleToRawLongBits(d);\r
+               if (a == 0) {\r
+                       this.mantissa = BigInteger.ZERO;\r
+                       this.exponent = BigInteger.ZERO;\r
+               } else {\r
+                       man = BigInteger.ONE;\r
+                       if ((a >>> 0x3f) == 1) {\r
+                               man = man.negate();\r
+                               a -= 1L << 0x3f;\r
+                       }\r
+                       exp = BigInteger.valueOf((a >>> 0x34) - 0x3ff - 0x34);\r
+                       a &= ((1L << 0x34) - 1);\r
+                       a += 1L << 0x34;\r
+                       man = man.multiply(BigInteger.valueOf(a));\r
+                       rt = new BinaryFloat(man, exp);\r
+                       this.exponent = rt.exponent;\r
+                       this.mantissa = rt.mantissa;\r
+               }\r
+       }\r
+\r
+       public double toDouble() {\r
+               long a;\r
+               double rt;\r
+               BinaryFloat bf;\r
+               BigInteger man, exp;\r
+               a = 0;\r
+               if (this.mantissa.signum() == 0)\r
+                       return 0;\r
+               if (this.mantissa.signum() == -1)\r
+                       a += 1L << 0x3f;\r
+               bf = this.newMantissaLength(0x35);\r
+               man = bf.mantissa.abs();\r
+               exp = bf.exponent\r
+                               .add(BigInteger.valueOf(bf.mantissa.abs().bitLength()));\r
+               exp = exp.add(new BigInteger("3FE", 0x10));\r
+               man = man.shiftLeft(0x35 - man.bitLength());\r
+               a += man.clearBit(0x34).longValue();\r
+               if ((exp.signum() == -1)\r
+                               || (exp.compareTo(new BigInteger("800", 0x10)) != -1))\r
+                       throw new Error();\r
+               a += (long) bigToInt(exp) << 0x34;\r
+               return Double.longBitsToDouble(a);\r
+       }\r
+\r
+       /**\r
+        * This creates a BinaryFloat with a given radix. The number entered is\r
+        * 0.mantissa * (radix ** exponent)\r
+        */\r
+       public BinaryFloat(BigInteger mantissa, int exponent, int radix) {\r
+               BinaryFloat rt, b;\r
+               long temp;\r
+               temp = exponent;\r
+               temp -= mantissa.toString(radix).length();\r
+               exponent = (int) temp;\r
+               if (exponent != temp)\r
+                       throw new Error();\r
+               rt = new BinaryFloat(mantissa);\r
+               if (exponent > 0) {\r
+                       rt = (BinaryFloat) rt.multiply(new BinaryFloat(BigInteger.valueOf(\r
+                                       radix).pow(exponent)));\r
+               } else if (exponent < 0) {\r
+                       rt = (BinaryFloat) rt.divide(new BinaryFloat(BigInteger.valueOf(\r
+                                       radix).pow(-exponent)));\r
+               }\r
+               rt = rt.newMantissaLength(mantissa_length);\r
+               this.mantissa = rt.mantissa;\r
+               this.exponent = rt.exponent;\r
+       }\r
+\r
+       /**\r
+        * Creates a new BinaryFloat equal to BigInteger b.\r
+        * \r
+        * @param b -\r
+        */\r
+       public BinaryFloat(BigInteger b) {\r
+               this(b, BigInteger.ZERO);\r
+       }\r
+\r
+       /**\r
+        * Returns truncated BinaryFloat as a BigInteger.\r
+        * \r
+        * @return a BigInteger representing this truncated.\r
+        */\r
+       public BigInteger toBigInteger() {\r
+               return shiftLeft(mantissa, bigToInt(exponent));\r
+       }\r
+\r
+       /**\r
+        * Basic constructor. Number represented is mantissa * (2 raised to\r
+        * exponent).\r
+        * \r
+        * @param mantissa -\r
+        * @param exponent -\r
+        */\r
+\r
+       public BinaryFloat(BigInteger mantissa, BigInteger exponent) {\r
+               this.exponent = exponent.add(BigInteger.valueOf(mantissa\r
+                               .getLowestSetBit()));\r
+               this.mantissa = shiftRight(mantissa, mantissa.getLowestSetBit());\r
+       }\r
+\r
+       /**\r
+        * The standard output gives a hexadecimal representation. The exponent\r
+        * symbol is "P".\r
+        * \r
+        * @return a String representing this.\r
+        */\r
+       public String toString() {\r
+               String rt = "";\r
+               BigInteger man, exp;\r
+               if (this.mantissa.signum() == 0)\r
+                       return "0";\r
+               exp = exponent.add(BigInteger.valueOf(mantissa.abs().bitLength()));\r
+               BigInteger remain = exp.remainder(new BigInteger("4"));\r
+               if (this.mantissa.signum() == -1)\r
+                       rt = "-";\r
+               man = this.mantissa.abs();\r
+               exp = exp.divide(new BigInteger("4"));\r
+               if (remain.signum() == 1)\r
+                       exp = exp.add(BigInteger.ONE);\r
+               man = shiftLeft(man, invRemainder(\r
+                               BigInteger.valueOf(man.abs().bitLength()).add(\r
+                                               new BigInteger("4")).subtract(remain),\r
+                               new BigInteger("4")).intValue());\r
+               rt += "0x0.";\r
+               rt += man.toString(0x10);\r
+               rt += "P";\r
+               rt += exp.toString(0x10);\r
+               return rt;\r
+       }\r
+\r
+       /**\r
+        * This outputs the raw mantissa and exponent, good for debugging.\r
+        */\r
+       public String toBinString() {\r
+               String rt = "";\r
+               if (this.mantissa.signum() == 0)\r
+                       return "0";\r
+               rt += this.mantissa.toString(0x2);\r
+               rt += "Pbin";\r
+               rt += this.exponent.toString(0x2);\r
+               return rt;\r
+       }\r
+\r
+       /**\r
+        * Returns a string representing this in the given radix. The length is the\r
+        * maximum digits (in the specified radix) to give.\r
+        * \r
+        * @param radix -\r
+        *            From 2 to 36 (24h)\r
+        * @param length -\r
+        */\r
+       public String toString(int radix, int length) {\r
+               String rt = "", manr;\r
+               BigInteger man, exp;\r
+               BinaryFloat bf;\r
+               int expsign = exponent.signum();\r
+               int i = 0;\r
+               int result;\r
+               if (length < 1)\r
+                       throw new Error();\r
+               if (this.mantissa.signum() == 0)\r
+                       return "0";\r
+               if (this.mantissa.signum() == -1)\r
+                       rt = "-";\r
+               rt += "0.";\r
+               if (expsign >= 0) {\r
+                       man = this.toBigInteger();\r
+                       manr = man.abs().toString(radix);\r
+               } else {\r
+                       exp = exponent.abs();\r
+                       while ((result = BigInteger.valueOf(radix).pow(-i).compareTo(\r
+                                       BigInteger.ONE.shiftLeft(bigToInt(exp)))) < 1)\r
+                               i--;\r
+                       if (result != 0)\r
+                               i--;\r
+                       bf = (BinaryFloat) this.multiply(new BinaryFloat(BigInteger\r
+                                       .valueOf(radix).pow(-i)));\r
+                       man = shiftLeft(bf.mantissa, bigToInt(bf.exponent));\r
+                       manr = man.abs().toString(radix);\r
+                       while ((manr.length() <= length) && (bf.exponent.signum() == -1)) {\r
+                               bf = (BinaryFloat) bf.multiply(new BinaryFloat(BigInteger\r
+                                               .valueOf(radix)));\r
+                               i--;\r
+                               man = shiftLeft(bf.mantissa, bigToInt(bf.exponent));\r
+                               manr = man.abs().toString(radix);\r
+                       }\r
+               }\r
+               i += manr.length();\r
+               if (manr.length() > length)\r
+                       rt += "~" + manr.substring(0, length);\r
+               else\r
+                       rt += manr;\r
+               while (rt.charAt(rt.length() - 1) == '0')\r
+                       rt = rt.substring(0, rt.length() - 1);\r
+               rt += "(Exponent)";\r
+               rt += Integer.toString(i, radix);\r
+               return rt;\r
+       }\r
+\r
+       /**\r
+        * Returns a new BinaryFloat with the given length as a maximum.\r
+        * \r
+        * @param length -\r
+        */\r
+       public BinaryFloat newMantissaLength(int length) {\r
+               BinaryFloat rt = new BinaryFloat(BigInteger.ZERO);\r
+               if (length < 1)\r
+                       throw new Error();\r
+               if (length >= mantissa.abs().bitLength())\r
+                       return this;\r
+               rt = new BinaryFloat(shiftRight(mantissa, mantissa.abs().bitLength()\r
+                               - length), exponent.add(BigInteger.valueOf(mantissa.abs()\r
+                               .bitLength()\r
+                               - length)));\r
+               return rt;\r
+       }\r
+\r
+       /**\r
+        * Compares this with specified.\r
+        * \r
+        * @return -1, 0, or 1 as this is, respectively, less than, equal to, or\r
+        *         greater than.\r
+        */\r
+       public int compareTo(BinaryFloat b) {\r
+               return ((BinaryFloat) (this.subtract(b))).mantissa.signum();\r
+       }\r
+\r
+       /**\r
+        * Addition.\r
+        */\r
+       public FieldElement add(FieldElement fe) {\r
+               BinaryFloat b = (BinaryFloat) fe;\r
+               BinaryFloat rt, temp;\r
+               BigInteger manx, many, expx, expy, manr, expr;\r
+               int lengthman, lengthexp;\r
+               if (b.mantissa.signum() == 0)\r
+                       return this;\r
+               if (this.mantissa.signum() == 0)\r
+                       return b;\r
+               manx = this.mantissa;\r
+               many = b.mantissa;\r
+               expx = this.exponent;\r
+               expy = b.exponent;\r
+               if (expx.compareTo(expy) == 1)\r
+                       manx = manx.shiftLeft(bigToInt(expx.subtract(expy)));\r
+               else {\r
+                       many = many.shiftLeft(bigToInt(expy.subtract(expx)));\r
+                       expy = expx;\r
+               }\r
+               expr = expy;\r
+               manr = manx.add(many);\r
+               if (manr.signum() == 0)\r
+                       return new BinaryFloat(BigInteger.ZERO);\r
+               rt = new BinaryFloat(manr, expr);\r
+               rt = newMantissaLength(mantissa_length);\r
+               return rt;\r
+       }\r
+\r
+       /**\r
+        * Multiplication\r
+        */\r
+       public FieldElement multiply(FieldElement fe) {\r
+               BinaryFloat b = (BinaryFloat) fe;\r
+               BinaryFloat rt;\r
+               if ((this.mantissa.signum() * b.mantissa.signum()) == 0)\r
+                       return new BinaryFloat(BigInteger.ZERO);\r
+               return new BinaryFloat(this.mantissa.multiply(b.mantissa),\r
+                               this.exponent.add(b.exponent));\r
+       }\r
+\r
+       /**\r
+        * Divide by the given BinaryFloat, using a maximum of i bits of precision\r
+        * in the result.\r
+        */\r
+       public FieldElement divide(FieldElement fe) throws DivisionByZeroException {\r
+               if (fe.isZero()) {\r
+                       throw new DivisionByZeroException("Tried to divide " + this + "by"\r
+                                       + fe + ".");\r
+               }\r
+               BinaryFloat b = (BinaryFloat) fe;\r
+               int i = mantissa_length;\r
+               BinaryFloat rt;\r
+               BigInteger manr, expr, remainder;\r
+               if (i < 1)\r
+                       throw new Error();\r
+               if (b.mantissa.signum() == 0)\r
+                       throw new Error();\r
+               if (this.mantissa.signum() == 0)\r
+                       return new BinaryFloat(BigInteger.ZERO);\r
+               expr = this.exponent.subtract(b.exponent);\r
+               manr = this.mantissa.divide(b.mantissa);\r
+               remainder = this.mantissa.abs().remainder(b.mantissa.abs());\r
+               while ((remainder.signum() == 1) && (manr.bitLength() < i)) {\r
+                       manr = manr.shiftLeft(1);\r
+                       expr = expr.subtract(BigInteger.ONE);\r
+                       remainder = remainder.shiftLeft(1);\r
+                       if (remainder.compareTo(b.mantissa) >= 0) {\r
+                               remainder = remainder.subtract(b.mantissa);\r
+                               manr = manr.setBit(0);\r
+                       }\r
+               }\r
+               rt = new BinaryFloat(manr, expr);\r
+               rt = rt.newMantissaLength(i);\r
+               return rt;\r
+       }\r
+\r
+       /**\r
+        * Returns a BinaryFloat whose value is <code>this**a</code>.\r
+        */\r
+       public FieldElement pow(int a) {\r
+               BinaryFloat rt;\r
+               if (mantissa.signum() == 0)\r
+                       if (a == 0)\r
+                               throw new Error();\r
+                       else\r
+                               return new BinaryFloat(BigInteger.ZERO);\r
+               if (a == 0)\r
+                       return new BinaryFloat(BigInteger.ONE);\r
+               rt = new BinaryFloat(this.mantissa.pow(Math.abs(a)), this.exponent\r
+                               .multiply(BigInteger.valueOf(Math.abs(a))));\r
+               if (a < 0)\r
+                       rt = (BinaryFloat) new BinaryFloat(BigInteger.ONE).divide(rt);\r
+               return rt;\r
+       }\r
+       /*\r
+        * public static void main (String args[]) { BinaryFloat bf=new\r
+        * BinaryFloat(new BigInteger("318728478278732872873"),new\r
+        * BigInteger("-2",0x10)); BinaryFloat bf1=new BinaryFloat(new\r
+        * BigInteger("1232983753"),2,0x1000,0xA); BinaryFloat bf2=new\r
+        * BinaryFloat(new BigInteger("23787821783"),0,0x1100,0xA);\r
+        * System.out.println(bf1.add(bf2).toString(0xA,0x100));\r
+        * System.out.println(bf1.sub(bf2).toString(0xA,0x100));\r
+        * System.out.println(bf1.mul(bf2).toString(0xA,0x100));\r
+        * System.out.println(bf1.div(bf2,0x100).toString(0xA,0x100));\r
+        * System.out.println(bf1.pow(-5).toString(0xA,0x10000));\r
+        * \r
+        * System.out.println(bf.toString(0xA,0x1000));\r
+        * System.out.println(bf.toBinString()); System.out.println(bf.toDouble()); }\r
+        */\r
+}\r
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/Complex.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/Complex.java
new file mode 100644 (file)
index 0000000..1bdf8d2
--- /dev/null
@@ -0,0 +1,246 @@
+package JLinAlg;
+
+/**
+ * This class represents a complex number with two Rationals as a
+ * real- and imaginary part.  Therefore there will not be any rounding
+ * errors.  Furthermore complex numbers and rational number are
+ * compatible in all operations.
+ * @author Andreas Keilhauer, Simon D. Levy
+ */
+
+public class Complex extends FieldElement {
+
+       /**
+        * The real part of this Complex as a Rational.
+        */
+
+       protected Rational realPart;
+
+       /**
+        * The imaginary part of this Complex as a Rational.
+        */
+
+       protected Rational imaginaryPart;
+
+       /**
+        * Creates a Complex out of two Rationals, representing real- and
+        * imaginary part.
+        *
+        * @param realPart
+        * @param imaginaryPart
+        */
+
+       public Complex(Rational realPart, Rational imaginaryPart) {
+               this.realPart = realPart;
+               this.imaginaryPart = imaginaryPart;
+       }
+
+       /**
+        * Creates a Complex out of two doubles, representing real- and
+        * imaginary part.
+        *
+        * @param realPart
+        * @param imaginaryPart
+        */
+
+       public Complex(double realPart, double imaginaryPart) {
+               this.realPart = new Rational(realPart);
+               this.imaginaryPart = new Rational(imaginaryPart);
+       }
+
+       /**
+        * Gets the real part of this complex.
+        *
+        * @return real part as a Rational
+        */
+
+       public Rational getReal() {
+               return realPart;
+       }
+
+       /**
+        * Gets the imaginary part of this complex.
+        *
+        * @return imaginary part as a Rational
+        */
+
+       public Rational getImaginary() {
+               return imaginaryPart;
+       }
+
+       /**
+        * Returns the result of this Complex added to another one.
+        */
+
+       public FieldElement add(FieldElement val) {
+               if (val instanceof Rational) {
+                       return new Complex(
+                               (Rational) (this.realPart.add(val)),
+                               this.imaginaryPart);
+               }
+               Complex added = (Complex) val;
+               Rational newRealPart = (Rational) this.realPart.add(added.getReal());
+               Rational newImaginaryPart =
+                       (Rational) this.imaginaryPart.add(added.getImaginary());
+               return new Complex(newRealPart, newImaginaryPart);
+       }
+
+       /**
+        * Returns the result of this Complex multiplied with another one.
+        */
+
+       public FieldElement multiply(FieldElement val) {
+               if (val instanceof Rational) {
+                       return new Complex(
+                               (Rational) (this.realPart.multiply(val)),
+                               (Rational) (this.imaginaryPart.multiply(val)));
+               }
+               Complex mult = (Complex) val;
+               Rational newRealPart =
+                       (Rational) (this.realPart.multiply(mult.getReal())).subtract(
+                               this.imaginaryPart.multiply(mult.getImaginary()));
+               Rational newImaginaryPart =
+                       (Rational) (this.realPart.multiply(mult.getImaginary())).add(
+                               this.imaginaryPart.multiply(mult.getReal()));
+               return new Complex(newRealPart, newImaginaryPart);
+       }
+
+       public FieldElement negate() {
+               return new Complex(
+                       (Rational) realPart.negate(),
+                       (Rational) imaginaryPart.negate());
+       }
+
+       public FieldElement invert() throws DivisionByZeroException {
+               if (this.isZero()) {
+                       throw new DivisionByZeroException("Tried to invert zero.");
+               }
+               Rational normalize =
+                       (Rational) this.realPart.multiply(this.realPart).add(
+                               this.imaginaryPart.multiply(this.imaginaryPart));
+               return new Complex(
+                       (Rational) this.realPart.divide(normalize),
+                       (Rational) this.imaginaryPart.negate().divide(normalize));
+       }
+
+       /**
+        * Returns a Complex that is this Complex conjugated.
+        *
+        * @return this Complex conjugated 
+        */
+
+       public Complex conjugate() {
+               return new Complex(realPart, (Rational) imaginaryPart.negate());
+       }
+
+       /**
+        * Determines whether two Complex numbers are mathematically equal.
+        *
+        * @param obj another Complex/Rational
+        * @return true if and only if the real- as well as the imaginary
+        * parts are equal.
+        */
+
+       public boolean equals(Object obj) {
+               if (obj instanceof Rational) {
+                       Rational comp = (Rational) obj;
+                       if (!this.imaginaryPart.isZero()) {
+                               return false;
+                       } else {
+                               return this.realPart.equals(comp);
+                       }
+               }
+               Complex comp = (Complex) obj;
+               return this.realPart.equals(comp.getReal())
+                       && this.imaginaryPart.equals(comp.getImaginary());
+       }
+
+       /**
+        * Returns the neutral element of addition.
+        *
+        * @return 0 + 0 * i
+        */
+
+       public FieldElement zero() {
+               return new Complex(new Rational(0), new Rational(0));
+       }
+
+       /**
+        * Returns the neutral element of multiplication.
+        *
+        * @return 1 + 0 * i
+        */
+
+       public FieldElement one() {
+               return new Complex(new Rational(1), new Rational(0));
+       }
+
+       /**
+        * Returns a String representation of this Complex.
+        */
+
+       public String toString() {
+               String tmp = "";
+
+               boolean reIsZero = this.realPart.isZero();
+               boolean imAbsIsOne = this.imaginaryPart.abs().isOne();
+               int compImZero = this.imaginaryPart.compareTo(new Rational(0));
+
+               if (!reIsZero || (reIsZero && compImZero == 0)) {
+                       tmp += this.realPart.toString();
+               }
+
+               if (compImZero != 0) {
+                       if (compImZero > 0 && !reIsZero) {
+                               tmp += " + ";
+                       } else if (compImZero < 0) {
+                               tmp += " - ";
+                       }
+
+                       if (!imAbsIsOne) {
+                               tmp += imaginaryPart.abs().toString() + " ";
+                       }
+                       tmp += "i";
+               }
+
+               return tmp;
+       }
+
+       /**
+        * Implements Comparable.compareTo(Object).  Comparison is based on 
+        * Rational magnitude value.
+        * @param o the object
+        * @return {-,+,0} as this object is less than, equal to, or
+        * greater than the specified object.
+        */
+
+       public int compareTo(Object o) {
+               Complex comp = (Complex) o;
+               return this.magnitude().compareTo(comp.magnitude());
+       }
+
+       /**
+        * Returns magnitude (sum of squares of real and imaginary components) of
+        * this Complex number.
+        * @return magnitude
+        */
+
+       public Rational magnitude() {
+               Rational a = getReal();
+               Rational b = getImaginary();
+               return (Rational) b.multiply(b).add(a.multiply(a));
+       }
+
+       /**
+        * Returns an instance of this FieldElement to be used in computing mean
+        * and other values.
+        *
+        * @param dval the value to use
+        * @return instance
+        */
+
+       public FieldElement instance(double dval) {
+               return new Complex(dval, 0);
+       }
+       
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/DiagonalMatrix.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/DiagonalMatrix.java
new file mode 100644 (file)
index 0000000..0398a3c
--- /dev/null
@@ -0,0 +1,688 @@
+package JLinAlg;\r
+\r
+/**\r
+ * This class represents a DiagonalMatrix.\r
+ *\r
+ * @author Lei Chen\r
+ * @author Veronika Ortner \r
+ * @author Safak Oekmen\r
+ */\r
+\r
+class DiagonalMatrix extends Matrix {\r
+\r
+       /*\r
+       * CONSTRUCTORS:\r
+       * Constructor1:\r
+       * DiagonalMatrix arising from array containing diagonal Elements.\r
+       */\r
+\r
+       /**\r
+        * @param diagElement array containing diagonal Elements.\r
+        */\r
+\r
+       public DiagonalMatrix(FieldElement[] diagElements)\r
+               throws InvalidOperationException {\r
+\r
+               super(diagElements.length, diagElements.length);\r
+\r
+               int arraysize = diagElements.length;\r
+\r
+               if (diagElements == null)\r
+                       throw new InvalidOperationException("Tried to construct DiagonalMatrix but diagElements array was null.");\r
+\r
+               for (int i = 0; i < arraysize; i++)\r
+                       for (int j = 0; j < arraysize; j++) {\r
+                               if (i != j)\r
+                                       //zero Element of FieldElement\r
+                                       entries[i][j] = diagElements[0].zero();\r
+                               else\r
+                                       entries[i][j] = diagElements[i];\r
+                       }\r
+       }\r
+\r
+       /*\r
+        * Constructor2:\r
+        * DiagonalMatrix in given size. \r
+        * Diagonal Elements are set diagElement.\r
+        */\r
+\r
+       /**\r
+        * @param size size of DiagonalMatrix to be constructed\r
+            * @param diagElement value of diagonal Elements\r
+        */\r
+\r
+       public DiagonalMatrix(int size, FieldElement diagElement) {\r
+\r
+               super(size, size);\r
+\r
+               for (int i = 0; i < size; i++)\r
+                       for (int j = 0; j < size; j++) {\r
+                               if (i == j)\r
+                                       entries[i][j] = diagElement;\r
+                               else\r
+                                       entries[i][j] = diagElement.zero();\r
+                       }\r
+       }\r
+\r
+       /*\r
+        * Methods:\r
+        * \r
+        * ADOPTED METHODS:\r
+        * getRows,getCols,getRow,getCol,withoutRow,\r
+            * withoutCol,insertRow,insertCol,toString,detCalc,\r
+            * isZeroRow,isZeroCol,hermitian\r
+        * \r
+        * TRANSCRIBED METHODS:\r
+        * getEntry,setEntry,setRow,setCol,add,\r
+            * subtract,multiply,copy,det,swapRows,\r
+            * swapCols,rank,inverse,transpose,equals,\r
+        * gausselim,gaussjord\r
+        * \r
+        * NEW METHODS:\r
+        * getDiagElement,setDiagElement,setRC,contZeroRow,getDiagonalElements\r
+        * toMatrix\r
+        */\r
+\r
+       /* \r
+        * getEntry:\r
+        * Getting particular Element at a given position in a DiagonalMatrix\r
+        */\r
+\r
+       /**\r
+        * @param rowIndex index of row in DiagonalMatrix\r
+        * @param colIndex index of col in DiagonalMatrix\r
+        * @return FieldElement\r
+        */\r
+\r
+       public FieldElement get(int rowIndex, int colIndex) {\r
+\r
+               if (rowIndex != colIndex)\r
+                       return this.get(1, 1).zero();\r
+               else\r
+                       return getDiagElement(rowIndex);\r
+       }\r
+\r
+       /* \r
+       * setEntry:\r
+       * Setting particular Element at given position in DiagonalMatrix\r
+       */\r
+\r
+       /**\r
+        * @param rowIndex index of row in DiagonalMatrix\r
+        * @param colIndex index of col in DiagonalMatrix\r
+        * @param newEntry FieldElement to be set\r
+        */\r
+\r
+       public void set(int rowIndex, int colIndex, FieldElement newEntry)\r
+               throws InvalidOperationException {\r
+\r
+               if (rowIndex != colIndex)\r
+                       throw new InvalidOperationException("Tried to set non-diagonal entry to a value different from zero.");\r
+               else\r
+                       setDiagElement(rowIndex, newEntry);\r
+       }\r
+\r
+       /**\r
+        * @param position row or column Index of FieldElement \r
+        * @return FieldElement\r
+        */\r
+\r
+       public FieldElement getDiagElement(int position)\r
+               throws InvalidOperationException {\r
+\r
+               int size = this.numOfRows;\r
+\r
+               if ((position > size) || (position < 0))\r
+                       throw new InvalidOperationException(\r
+                               "Tried to get Element at Position "\r
+                                       + position\r
+                                       + ". Size of Matrix:\n "\r
+                                       + size);\r
+               else\r
+                       return this.entries[position - 1][position - 1];\r
+       }\r
+\r
+       /**\r
+        * @param position row or column index of DiagonalMatrix \r
+        * @param elem FieldElement to be set\r
+        */\r
+\r
+       public void setDiagElement(int position, FieldElement elem)\r
+               throws InvalidOperationException {\r
+\r
+               int size = this.numOfRows;\r
+\r
+               if ((position > size) || (position < 0))\r
+                       throw new InvalidOperationException(\r
+                               "Tried to set Element at Position\n"\r
+                                       + position\r
+                                       + ". Size of Matrix:\n "\r
+                                       + size);\r
+               else\r
+                       this.entries[position - 1][position - 1] = elem;\r
+       }\r
+\r
+       /*\r
+        * setRow/setCol\r
+        * replacing row or column with given vector\r
+        */\r
+\r
+       /**\r
+        * @param rowIndex index of row to be replaced\r
+        * @param vector vector to be set\r
+        */\r
+\r
+       public void setRow(int rowIndex, Vector vector) {\r
+\r
+               setRC(rowIndex, vector);\r
+\r
+       }\r
+\r
+       /**\r
+       * @param colIndex index of col to be replaced\r
+       * @param vector vector to be set\r
+       */\r
+\r
+       public void setCol(int colIndex, Vector vector) {\r
+\r
+               setRC(colIndex, vector);\r
+\r
+       }\r
+\r
+       /**\r
+        * @param rcIndex row or column index of DiagonalMatrix\r
+        * @param vector vector to be set\r
+        */\r
+\r
+       private void setRC(int rcIndex, Vector vector)\r
+               throws InvalidOperationException {\r
+\r
+               int vectorsize = vector.length();\r
+\r
+               int size = this.numOfRows;\r
+\r
+               if (size != vectorsize)\r
+                       throw new InvalidOperationException("Tried to set a row with a voctor of invalid size.");\r
+\r
+               for (int i = 1; i <= vectorsize; i++) {\r
+                       if (i != rcIndex) {\r
+                               if (!(vector.getEntry(i).equals(vector.getEntry(1).zero())))\r
+                                       throw new InvalidOperationException("Tried to set a non-diagonal entry to a value different from zero.");\r
+                       }\r
+               }\r
+               setDiagElement(rcIndex, vector.getEntry(rcIndex));\r
+       }\r
+\r
+       /*\r
+        * add/subtract\r
+        */\r
+\r
+       /**\r
+        * @param diagMatrix diagonal Matrix to be added \r
+        * @return sum of diagonal matrices\r
+        */\r
+\r
+       public DiagonalMatrix add(DiagonalMatrix diagMatrix)\r
+               throws InvalidOperationException {\r
+\r
+               if (this.numOfCols != diagMatrix.numOfRows)\r
+                       throw new InvalidOperationException(\r
+                               "Tried to sum up \n"\r
+                                       + this\r
+                                       + "and \n"\r
+                                       + diagMatrix\r
+                                       + "No correct format!");\r
+\r
+               DiagonalMatrix tmp = (DiagonalMatrix) this.copy();\r
+\r
+               for (int i = 1; i <= tmp.getRows(); i++)\r
+                       tmp.set(\r
+                               i,\r
+                               i,\r
+                               this.get(i, i).add(diagMatrix.get(i, i)));\r
+\r
+               return tmp;\r
+       }\r
+\r
+       /*\r
+        * adding square matrix not being DiagonalMatrix\r
+        */\r
+\r
+       /**\r
+        * @param matrix matrix to be added to this DiagonalMatrix\r
+        * @return addition of this DiagonalMatrix plus matrix\r
+        */\r
+\r
+       public Matrix add(Matrix matrix) throws InvalidOperationException {\r
+\r
+               //size of this: axa; size of matrix: cxd or axd\r
+               if ((this.numOfCols != matrix.numOfRows)\r
+                       || (this.numOfCols != matrix.numOfCols))\r
+                       throw new InvalidOperationException(\r
+                               "Tried to sum up \n"\r
+                                       + this\r
+                                       + "and \n"\r
+                                       + matrix\r
+                                       + "No correct format!");\r
+\r
+               Matrix tmp = matrix.copy();\r
+\r
+               for (int i = 1; i <= tmp.numOfRows; i++)\r
+                       tmp.set(i, i, this.get(i, i).add(matrix.get(i, i)));\r
+\r
+               return tmp;\r
+       }\r
+\r
+       /**\r
+        * @param diagMatrix matrix to be subtracted from this DiagonalMatrix\r
+        * @return Difference of this DiagonalMatrix and diagMatrix \r
+        */\r
+\r
+       public DiagonalMatrix subtract(DiagonalMatrix diagMatrix)\r
+               throws InvalidOperationException {\r
+\r
+               //size of each DiagonalMatrix is different\r
+               if (this.numOfCols != diagMatrix.numOfRows)\r
+                       throw new InvalidOperationException(\r
+                               "Tried to subtract \n"\r
+                                       + diagMatrix\r
+                                       + "from \n"\r
+                                       + this\r
+                                       + "No correct format!");\r
+\r
+               DiagonalMatrix tmp =\r
+                       new DiagonalMatrix(\r
+                               this.numOfRows,\r
+                               diagMatrix.get(1, 1).zero());\r
+\r
+               for (int i = 1; i <= tmp.numOfRows; i++)\r
+                       tmp.set(\r
+                               i,\r
+                               i,\r
+                               this.get(i, i).subtract(diagMatrix.get(i, i)));\r
+               return tmp;\r
+\r
+       }\r
+\r
+       /**\r
+        * @param matrix matrix to be subtracted from this DiagonalMatrix\r
+        * @return Difference between this DiagonalMatrix and Matrix \r
+        */\r
+\r
+       public Matrix subtract(Matrix matrix) throws InvalidOperationException {\r
+\r
+               if (this.numOfCols != matrix.numOfRows)\r
+                       throw new InvalidOperationException(\r
+                               "Tried to subtract \n"\r
+                                       + matrix\r
+                                       + "from \n"\r
+                                       + this\r
+                                       + "No correct format!");\r
+\r
+               Matrix tmp = new Matrix(this.numOfRows, matrix.numOfCols);\r
+\r
+               for (int i = 1; i <= tmp.numOfRows; i++)\r
+                       for (int j = 1; j <= tmp.numOfCols; j++)\r
+                               tmp.set(\r
+                                       i,\r
+                                       j,\r
+                                       this.get(i, j).subtract(matrix.get(i, j)));\r
+\r
+               return tmp;\r
+       }\r
+\r
+       /*\r
+            * Returns a DiagonalMatrix that is this DiagonalMatrix multiplied with a scalar\r
+        */\r
+\r
+       /**\r
+        * @param scalar scalar FieldElement that is multiplied to this DiagonalMatrix\r
+        * scalar * DiagonalMatrix\r
+        * @return DiagonalMatrix\r
+        */\r
+\r
+       public Matrix multiply(FieldElement scalar) {\r
+\r
+               int size = this.getRows();\r
+\r
+               DiagonalMatrix diagMatrix = new DiagonalMatrix(size, scalar.zero());\r
+\r
+               for (int i = 0; i < size; i++)\r
+                       diagMatrix.entries[i][i] = this.entries[i][i].multiply(scalar);\r
+\r
+               return diagMatrix;\r
+       }\r
+\r
+       /*\r
+        * Returns vector that is the product of this \r
+        * DiagonalMatrix and given vector. Multiplication from right.\r
+        */\r
+\r
+       /**\r
+        * @param vector vector that is multiplied to this DiagonalMatrix\r
+        * this * vector\r
+        * @return Vector\r
+        */\r
+\r
+       public Vector multiply(Vector vector) throws InvalidOperationException {\r
+\r
+               if (this.numOfCols != vector.length()) {\r
+                       throw new InvalidOperationException(\r
+                               "Tried to multiply \n"\r
+                                       + this\r
+                                       + "and \n"\r
+                                       + vector\r
+                                       + "No correct format!");\r
+\r
+               }\r
+\r
+               FieldElement[] result = new FieldElement[this.numOfRows];\r
+\r
+               for (int i = 1; i <= this.getRows(); i++)\r
+                       result[i - 1] = entries[i - 1][i - 1].multiply(vector.getEntry(i));\r
+\r
+               Vector resultVector = new Vector(result);\r
+\r
+               return resultVector;\r
+       }\r
+\r
+       /*\r
+        * Matrix that is the product of this DiagonalMatrix \r
+        * and another Matrix.\r
+        * Multiplication from right\r
+        */\r
+\r
+       /**\r
+        * @param matrix matrix that is multiplied to this DiagonalMatrix\r
+        * "this * matrix"\r
+        * @return Matrix\r
+        */\r
+\r
+       public Matrix multiply(Matrix matrix) throws InvalidOperationException {\r
+\r
+               if (this.numOfCols != matrix.getRows()) {\r
+                       throw new InvalidOperationException(\r
+                               "Tried to multiply \n"\r
+                                       + this\r
+                                       + "and \n"\r
+                                       + matrix\r
+                                       + "No correct format!");\r
+\r
+               }\r
+\r
+               Matrix resultMatrix = new Matrix(this.getRows(), matrix.getCols());\r
+\r
+               for (int i = 1; i <= matrix.numOfRows; i++)\r
+                       for (int j = 1; j <= matrix.numOfCols; j++)\r
+                               resultMatrix.set(\r
+                                       i,\r
+                                       j,\r
+                                       this.entries[i - 1][i - 1].multiply(matrix.get(i, j)));\r
+\r
+               return resultMatrix;\r
+\r
+       }\r
+\r
+       /*\r
+       * Matrix that is the product of this DiagonalMatrix \r
+       * and another DiagonalMatrix.\r
+       * Multiplication from right\r
+       */\r
+\r
+       /**\r
+       * @param diagMatrix DiagonalMatrix that is multiplied to this DiagonalMatrix\r
+       * "this * diagMatrix"\r
+       * @return DiagonalMatrix\r
+       */\r
+\r
+       public DiagonalMatrix multiply(DiagonalMatrix diagMatrix)\r
+               throws InvalidOperationException {\r
+\r
+               if (this.numOfCols != diagMatrix.getRows())\r
+                       throw new InvalidOperationException(\r
+                               "Tried to multiply \n"\r
+                                       + this\r
+                                       + "and \n"\r
+                                       + diagMatrix\r
+                                       + "No correct format!");\r
+\r
+               DiagonalMatrix result =\r
+                       new DiagonalMatrix(\r
+                               this.getRows(),\r
+                               diagMatrix.get(1, 1).zero());\r
+\r
+               for (int i = 1; i <= diagMatrix.numOfRows; i++)\r
+                       result.setDiagElement(\r
+                               i,\r
+                               this.entries[i - 1][i - 1].multiply(diagMatrix.get(i, i)));\r
+\r
+               return result;\r
+       }\r
+\r
+       /*\r
+        * copy()\r
+        */\r
+\r
+       /**\r
+        * @return DiagonalMatrix\r
+        */\r
+\r
+       public Matrix copy() {\r
+\r
+               DiagonalMatrix result =\r
+                       new DiagonalMatrix(this.getRows(), this.get(1, 1).zero());\r
+\r
+               for (int i = 0; i < getRows(); i++)\r
+                       result.entries[i][i] = this.entries[i][i];\r
+\r
+               return result;\r
+       }\r
+\r
+       /*\r
+        * det()\r
+        */\r
+\r
+       /**\r
+        * @param dm DiagonalMatrix for which the determinant is calculated\r
+        * @return FieldElement\r
+        */\r
+\r
+       public FieldElement det() {\r
+\r
+               FieldElement result = this.get(1, 1).one();\r
+\r
+               FieldElement[] diagonalElements = getDiagonalElements();\r
+\r
+               for (int i = 0; i < getRows(); i++)\r
+                       result = result.multiply(diagonalElements[i]);\r
+\r
+               return result;\r
+       }\r
+\r
+       /*\r
+        * swapRows,swapCols\r
+        */\r
+\r
+       /**\r
+        * @param rowIndex1 index of first swap partner.\r
+        * @param rowIndex1 index of second swap partner.\r
+        */\r
+\r
+       public void swapRows(int rowIndex1, int rowIndex2)\r
+               throws InvalidOperationException {\r
+\r
+               throw new InvalidOperationException("swapRows is not allowed in diagonal matrices.");\r
+\r
+       }\r
+\r
+       /**\r
+        * @param colIndex1 index of first swap partner.\r
+        * @param colIndex1 index of second swap partner.\r
+        */\r
+\r
+       public void swapCols(int colIndex1, int colIndex2)\r
+               throws InvalidOperationException {\r
+\r
+               throw new InvalidOperationException("swapCols is not allowed in diagonal matrices.");\r
+       }\r
+\r
+       /*\r
+        * rank() \r
+        */\r
+\r
+       public int rank() {\r
+\r
+               int nonZeroRows = 0;\r
+\r
+               for (int i = 0; i < this.numOfRows; i++) {\r
+                       if (!(isZeroRow(i + 1)))\r
+                               nonZeroRows++;\r
+               }\r
+\r
+               return nonZeroRows;\r
+       }\r
+\r
+       /*\r
+        * contZeroRow()\r
+        */\r
+\r
+       /**\r
+        * @return Boolean\r
+        */\r
+\r
+       public boolean contZeroRow() {\r
+\r
+               for (int i = 1; i <= numOfRows; i++) {\r
+                       if (isZeroRow(i))\r
+                               return true;\r
+               }\r
+               return false;\r
+\r
+       }\r
+\r
+       /*\r
+        * getDiagonalElements()\r
+        */\r
+\r
+       /**\r
+        * @return FieldElement[]\r
+        */\r
+\r
+       public FieldElement[] getDiagonalElements() {\r
+\r
+               FieldElement[] diagElements = new FieldElement[numOfRows];\r
+\r
+               for (int i = 0; i < numOfRows; i++)\r
+                       diagElements[i] = entries[i][i];\r
+\r
+               return diagElements;\r
+\r
+       }\r
+\r
+       /*\r
+        * inverse\r
+        */\r
+\r
+       /**\r
+        * @return DiagonalMatrix\r
+        */\r
+\r
+       public Matrix inverse() throws InvalidOperationException {\r
+\r
+               DiagonalMatrix reverse =\r
+                       new DiagonalMatrix(this.numOfRows, this.get(1, 1).zero());\r
+\r
+               if (this.contZeroRow())\r
+                       throw new InvalidOperationException("Not invertible.");\r
+\r
+               else {\r
+\r
+                       for (int i = 1; i <= numOfRows; i++)\r
+                               reverse.set(i, i, this.get(i, i).invert());\r
+\r
+               }\r
+\r
+               return reverse;\r
+\r
+       }\r
+\r
+       /*\r
+        * transpose()\r
+        */\r
+\r
+       /**\r
+        * @return DiagonalMatrix\r
+        */\r
+\r
+       public Matrix transpose() {\r
+\r
+               return this.copy();\r
+       }\r
+\r
+       /*\r
+        * equals\r
+        */\r
+\r
+       /**\r
+        * @param anotherMatrix Matrix that is collated to this DiagonalMatrix\r
+        * @return Boolean\r
+        */\r
+\r
+       public boolean equals(DiagonalMatrix anotherDiagMatrix) {\r
+\r
+               if (anotherDiagMatrix.getRows() != this.getRows())\r
+                       return false;\r
+\r
+               else {\r
+\r
+                       for (int i = 0; i < numOfRows; i++) {\r
+\r
+                               if (entries[i][i] != anotherDiagMatrix.entries[i][i])\r
+                                       return false;\r
+\r
+                       }\r
+                       return true;\r
+               }\r
+\r
+       }\r
+\r
+       /*\r
+        * gausselim & gaussjord\r
+        */\r
+\r
+       /**\r
+        * @return DiagonalMatrix\r
+        */\r
+\r
+       public Matrix gaussjord() {\r
+\r
+               return this.copy();\r
+\r
+       }\r
+\r
+       /**\r
+        * @return DiagonalMatrix\r
+        */\r
+\r
+       public Matrix gausselim() {\r
+\r
+               return this.copy();\r
+       }\r
+\r
+       /**\r
+        * @return Matrix\r
+        */\r
+\r
+       public Matrix toMatrix() {\r
+\r
+               Matrix result = new Matrix(this.numOfRows, this.numOfCols);\r
+\r
+               for (int i = 1; i <= this.numOfRows; i++)\r
+                       for (int j = 1; j <= this.numOfCols; j++)\r
+                               result.set(i, j, this.get(i, j));\r
+\r
+               return result;\r
+\r
+       }\r
+\r
+}\r
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/DivideOperator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/DivideOperator.java
new file mode 100644 (file)
index 0000000..017ebb0
--- /dev/null
@@ -0,0 +1,12 @@
+package JLinAlg;
+
+
+
+// division of two FieldElements
+class DivideOperator implements DyadicOperator {
+
+       public FieldElement apply(FieldElement x, FieldElement y) {
+               return x.divide(y);
+       }
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/DivisionByZeroException.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/DivisionByZeroException.java
new file mode 100644 (file)
index 0000000..9467ff4
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+ * Created on 15.05.2005\r
+ *\r
+ * To change the template for this generated file go to\r
+ * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments\r
+ */\r
+package JLinAlg;\r
+\r
+/**\r
+ * @author Andreas\r
+ *\r
+ * To change the template for this generated type comment go to\r
+ * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments\r
+ */\r
+public class DivisionByZeroException extends RuntimeException {\r
+\r
+       public DivisionByZeroException(String theMessage) {\r
+               super(theMessage);\r
+       }\r
+       \r
+}\r
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/DoubleWrapper.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/DoubleWrapper.java
new file mode 100644 (file)
index 0000000..ffe20ca
--- /dev/null
@@ -0,0 +1,190 @@
+package JLinAlg;
+
+/**
+ * This class wraps a double value and performs all FieldElement operations on
+ * that double. Fast but not without rounding errors.
+ * 
+ * @author Andreas Keilhauer
+ */
+
+public class DoubleWrapper extends FieldElement {
+
+       protected double value;
+
+       /**
+        * Builds an element from a double-precision floating-point value.
+        */
+       public DoubleWrapper(double value) {
+               this.value = value;
+       }
+
+       public double getValue() {
+               return this.value;
+       }
+
+       /**
+        * Calculates the sum of this element and another one.
+        * 
+        * @param val
+        * @return sum
+        */
+       public FieldElement add(FieldElement val) {
+               DoubleWrapper added = (DoubleWrapper) val;
+               return new DoubleWrapper(this.value + added.value);
+       }
+
+       /**
+        * Calculates the product of this element and another one.
+        * 
+        * @param val
+        * @return product
+        */
+       public FieldElement subtract(FieldElement val) {
+               DoubleWrapper sub = (DoubleWrapper) val;
+               return new DoubleWrapper(this.value - sub.value);
+       }
+
+       /**
+        * Calculates the product of this element and another one.
+        * 
+        * @param val
+        * @return product
+        */
+       public FieldElement multiply(FieldElement val) {
+               DoubleWrapper mult = (DoubleWrapper) val;
+               return new DoubleWrapper(this.value * mult.value);
+       }
+
+       /**
+        * Calculates the quotient of this element and another one.
+        * 
+        * @param val
+        * @return this / val
+        */
+       public FieldElement divide(FieldElement val) throws DivisionByZeroException {
+               if (val.isZero()) {
+                       throw new DivisionByZeroException("Tried to divide " + this + "by"
+                                       + val + ".");
+               }
+               DoubleWrapper div = (DoubleWrapper) val;
+               return new DoubleWrapper(this.value / div.value);
+       }
+
+       /**
+        * Calculates the inverse element of addition for this element.
+        * 
+        * @return negated (-value)
+        */
+       public FieldElement negate() {
+               return new DoubleWrapper(-this.value);
+       }
+
+       /**
+        * Calculates the inverse element of multiplication for this element.
+        * 
+        * @return inverted (1/value)
+        * @throws InvalidOperationException
+        *             if original value is zero
+        */
+       public FieldElement invert() throws DivisionByZeroException {
+               if (this.isZero()) {
+                       throw new DivisionByZeroException("Tried to invert zero.");
+               }
+               return new DoubleWrapper(1.0 / this.value);
+       }
+
+       /**
+        * Returns the neutral element of addition (zero element) of this
+        * FieldElement's field.
+        * 
+        * @return zero
+        */
+       public FieldElement zero() {
+               return new DoubleWrapper(0);
+       }
+
+       /**
+        * Returns the neutral element of multiplication (one element) of this
+        * element's field.
+        * 
+        * @return one
+        */
+       public FieldElement one() {
+               return new DoubleWrapper(1);
+       }
+
+       /**
+        * Checks two FieldElements for equality.
+        * 
+        * @param obj
+        * @return true if the two FieldElements are mathematically equal.
+        */
+       public boolean equals(Object obj) {
+               DoubleWrapper comp = (DoubleWrapper) obj;
+               return this.value == comp.value;
+       }
+
+       /**
+        * Returns a String representation of this element.
+        * 
+        * @return String representation
+        */
+       public String toString() {
+               return "" + this.value;
+       }
+
+       /**
+        * Returns the double-precision floating-point value of this element.
+        * 
+        * @return value
+        */
+       public double doubleValue() {
+               return this.value;
+       }
+
+       /**
+        * Implements Comparable.compareTo(Object).
+        * 
+        * @param o
+        *            the object
+        * @return {-,+,0} as this object is less than, equal to, or greater than
+        *         the specified object.
+        */
+       public int compareTo(Object o) {
+               DoubleWrapper comp = (DoubleWrapper) o;
+               return this.value < comp.value ? -1 : (this.value > comp.value ? 1 : 0);
+       }
+
+       /**
+        * Returns the square root of this value.
+        * 
+        * @return sqrt(value)
+        */
+       public double sqrt() {
+               return Math.sqrt(this.value);
+       }
+
+       /**
+        * Returns an instance of this FieldElement to be used in computing mean and
+        * other values.
+        * 
+        * @param dval
+        *            the value to use
+        * @return instance
+        */
+
+       public FieldElement instance(double dval) {
+               return new DoubleWrapper(dval);
+       }
+
+       /**
+        * Returns a DoubleWrapper with wrapped value greater than or equal to 0.0
+        * and less than 1.0 . Returned values are chosen pseudorandomly with
+        * (approximately) uniform distribution from that range.
+        */
+
+       public FieldElement randomValue() {
+               return new DoubleWrapper(Math.random());
+       }
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/DyadicOperator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/DyadicOperator.java
new file mode 100644 (file)
index 0000000..0177445
--- /dev/null
@@ -0,0 +1,25 @@
+package JLinAlg;
+
+
+
+/**
+ * The <i>DyadicOperator</i> interface supports application of
+ * arbitrary dyadic (two-argument) functions to the elements of two
+ * Matrix or Vector objects, via the Matrix or Vector's
+ * <tt>apply</tt> methods.
+ *
+ * @author Simon Levy
+ */
+
+public interface DyadicOperator{
+
+       /**
+        * Applies the function to two elements.
+        * @param x the value of one element
+        * @param y the value of the other element
+        * @return the result of applying the function to <tt>x</tt> and
+        * <tt>y</tt>
+        */
+       public FieldElement apply(FieldElement x, FieldElement y);
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/EqualToComparator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/EqualToComparator.java
new file mode 100644 (file)
index 0000000..54581cd
--- /dev/null
@@ -0,0 +1,11 @@
+package JLinAlg;
+
+
+// class to return FieldElement.one() or FieldElement.zero(), depending on 
+// result of FieldElement equal-to comparison
+class EqualToComparator extends FEComparator {
+
+       public boolean compare(FieldElement a, FieldElement b) {
+               return a.equals(b);
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/F2.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/F2.java
new file mode 100644 (file)
index 0000000..9d7ecb0
--- /dev/null
@@ -0,0 +1,184 @@
+package JLinAlg;
+
+/**
+ * This class represents an element of the modulo 2 field F2.
+ * F2 is a field, just like the rational numbers are.
+ * At first glance it seems to be a rather academic example,
+ * but prime fields (especially F2) have numerous applications
+ * (e.g.: error correcting codes).
+ * @author Andreas Keilhauer
+ */
+
+public class F2 extends FieldElement implements Comparable {
+
+       protected int value;
+
+       /**
+        * Builds an element from an integer value.  The resulting value is 
+        * simply this integer value modulo 2.
+        */
+       public F2(int value) {
+               this.value = value % 2;
+       }
+
+       /**
+        * Calculates the sum of this element and another one.
+        *
+        * @param val
+        * @return sum <=> logical XOR
+        */
+       public FieldElement add(FieldElement val) {
+               F2 added = (F2) val;
+               if ((this.value == 1 && added.value == 0)
+                       || this.value == 0
+                       && added.value == 1) {
+                       return new F2(1);
+               }
+               return new F2(0);
+       }
+
+       /**
+        * Calculates the difference between this element and another one.
+        *
+        * @param val
+        * @return difference <=> logical XOR
+        */
+       public FieldElement subtract(FieldElement val) {
+               F2 subtracted = (F2) val;
+               if ((this.value == 1 && subtracted.value == 0)
+                       || this.value == 0
+                       && subtracted.value == 1) {
+                       return new F2(1);
+               }
+               return new F2(0);
+       }
+
+       /**
+        * Calculates the product of this element and another one.
+        *
+        * @param val
+        * @return product <=> logical AND 
+        */
+       public FieldElement multiply(FieldElement val) {
+               F2 factor = (F2) val;
+               if (this.value == 1 && factor.value == 1) {
+                       return new F2(1);
+               }
+               return new F2(0);
+       }
+
+       /**
+        * Calculates the quotient of this FieldElement and another one.
+        *
+        * @param val
+        * @return quotient <=> this value if val = 1m2 and undefined (Exception) otherwise
+        * @throws InvalidOperationException if val = 0m2
+        */
+       public FieldElement divide(FieldElement val) {
+               F2 divisor = (F2) val;
+               if (divisor.value == 1) {
+                       return new F2(this.value);
+               }
+               throw new InvalidOperationException("Division by 0");
+       }
+
+       /**
+        * Calculates the inverse element of addition for this element.
+        *
+        * @return negated <=> this value
+        */
+       public FieldElement negate() {
+               return new F2(this.value);
+       }
+
+       /**
+        * Calculates the inverse element of multiplication for this element.
+        *
+        * @return inverted (i.e., the value itself)
+        * @throws DivisionByZeroException if this is zero
+        */
+       public FieldElement invert() throws DivisionByZeroException {
+               if (this.value == 0) {
+                       throw new DivisionByZeroException("Tried to invert zero.");
+               }
+               return new F2(this.value);
+       }
+
+       /**
+        * Returns the neutral element of addition (zero element) of this
+        * FieldElement's field.
+        *
+        * @return zero
+        */
+       public FieldElement zero() {
+               return new F2(0);
+       }
+
+       /**
+        * Returns the neutral element of multiplication (one element) of
+        * this element's field.
+        *
+        * @return one
+        */
+       public FieldElement one() {
+               return new F2(1);
+       }
+
+       /**
+        * Checks two elements for equality.
+        *
+        * @param val
+        * @return true if the two FieldElements are mathematically equal.
+        */
+       public boolean equals(FieldElement val) {
+               F2 comp = (F2) val;
+               return this.value == comp.value;
+       }
+
+       /**
+        * Returns a String representation of this element.
+        *
+        * @return String representation
+        */
+       public String toString() {
+               return this.value + "m2";
+       }
+
+       /**
+        * Implements Comparable.compareTo(Object).
+        * @param o the object
+        * @return {-,+,0} as this object is less than, equal to, or
+        * greater than the specified object.
+        */
+       public int compareTo(Object o) {
+               F2 comp = (F2) o;
+               return (value < comp.value) ? -1 : (value > comp.value ? 1 : 0);
+       }
+
+       /**
+        * Returns an instance of this FieldElement to be used in computing mean
+        * and other values.
+        *
+        * @param dval the value to use
+        * @return instance
+        */
+       public FieldElement instance(double dval) {
+               return new F2((int) dval);
+       }
+
+       /**
+        * Changed standard implementation for mapRandomValue a little
+        * to ensure that both elements of F2 are equally likely in
+        * the uniformly distributed case - LinAlgFactory.randomValue()
+        * <BR><STRONG>Note!</STRONG> Normal Distribution Issue<BR>
+        * In case of a normally distributed double as in 
+        * LinAlgFactory.gaussianRandomValue() it won't give you the
+        * right distribution. 
+        * 
+        * @param dval
+        * @return mapped value
+        */
+       public FieldElement mapRandomValue(double dval) {
+               return instance(dval * 2);
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/FEComparator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/FEComparator.java
new file mode 100644 (file)
index 0000000..d77d4dd
--- /dev/null
@@ -0,0 +1,9 @@
+package JLinAlg;
+
+
+// abstract class to return FieldElement.one() or FieldElement.zero(),
+// depending on result of comparison
+abstract class FEComparator {
+
+       public abstract boolean compare(FieldElement a, FieldElement b);
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/FieldElement.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/FieldElement.java
new file mode 100644 (file)
index 0000000..1bd18d6
--- /dev/null
@@ -0,0 +1,228 @@
+package JLinAlg;
+
+import java.io.Serializable;
+import java.util.Random;
+
+/**
+ * This class represents an element of an arbitrary field. It has to have four
+ * operations (add, subtract, multiply, divide) a neutral element of addition
+ * (zero) and a neutral element of multiplication (one). Concrete number types
+ * (fields) can be easily implemented by extending this class. <BR>
+ * <STRONG>Note! </STRONG> Performance Issue <BR>
+ * Most non abstract methods in this class were only implemented to make the
+ * process of implementing a new FieldElement convenient and short. These
+ * methods should be overwritten, whenever one is more interested in performance
+ * than in just getting something that works.
+ * 
+ * 
+ * @author Andreas Keilhauer, Simon D. Levy
+ */
+
+public abstract class FieldElement implements Comparable, Serializable {
+
+       /**
+        * Calculates the sum of this FieldElement and another one.
+        * 
+        * @param val
+        * @return sum
+        */
+
+       public abstract FieldElement add(FieldElement val);
+
+       /**
+        * Calculates the difference of this FieldElement and another one.
+        * 
+        * @param val
+        * @return difference
+        */
+
+       public FieldElement subtract(FieldElement val) {
+               return this.add(val.negate());
+       }
+
+       /**
+        * Calculates the product of this FieldElement and another one.
+        * 
+        * @param val
+        * @return product
+        */
+
+       public abstract FieldElement multiply(FieldElement val);
+
+       /**
+        * Calculates the quotient of this FieldElement and another one.
+        * 
+        * @param val
+        * @return quotient
+        */
+
+       public FieldElement divide(FieldElement val) throws DivisionByZeroException {
+               if (val.isZero()) {
+                       throw new DivisionByZeroException("Tried to divide " + this + "by"
+                                       + val + ".");
+               }
+               return this.multiply(val.invert());
+       }
+
+       /**
+        * Returns the neutral element of addition (zero element) of this
+        * FieldElement's field.
+        * 
+        * @return zero
+        */
+
+       public abstract FieldElement zero();
+
+       /**
+        * Returns the neutral element of multiplication (one element) of this
+        * FieldElement's field.
+        * 
+        * @return one
+        */
+
+       public abstract FieldElement one();
+
+       /**
+        * Calculates the inverse element of addition for this FieldElement.
+        * 
+        * @return negated
+        */
+
+       public abstract FieldElement negate();
+
+       /**
+        * Calculates the inverse element of multiplication for this FieldElement.
+        * 
+        * @return inverted
+        */
+
+       public abstract FieldElement invert() throws DivisionByZeroException;
+
+       /**
+        * Determines whether or not two FieldElements are equal.
+        * 
+        * @param obj
+        * @return true if the two FieldElements are mathematically equal.
+        */
+
+       public boolean equals(Object obj) {
+               return this.compareTo((FieldElement) obj) == 0;
+       }
+
+       /**
+        * Tests if this FieldElement is the neutral element of addition (zero).
+        * 
+        * @return true if zero
+        */
+
+       public boolean isZero() {
+               return this.equals(this.zero());
+       }
+
+       /**
+        * Tests if this FieldElement is the neutral element of multiplication
+        * (one).
+        * 
+        * @return true if one
+        */
+
+       public boolean isOne() {
+               return this.equals(this.one());
+       }
+
+       /**
+        * Implements Comparable.compareTo(Object).
+        * 
+        * @param o
+        *            the object
+        * @return {-,+,0} as this object is less than, equal to, or greater than
+        *         the specified object.
+        */
+
+       public abstract int compareTo(Object o);
+
+       /**
+        * Checks whether this FieldElement is mathematically less than another.
+        * 
+        * @param val
+        * @return true if this FieldElement is less than val, false otherwise
+        */
+
+       public boolean lt(FieldElement val) {
+               return this.compareTo(val) < 0;
+       }
+
+       /**
+        * Checks whether this FieldElement is mathematically greater than another.
+        * 
+        * @param val
+        * @return true if this FieldElement is greater than val, false otherwise
+        */
+
+       public boolean gt(FieldElement val) {
+               return !this.lt(val) && !this.equals(val);
+       }
+
+       /**
+        * Checks whether this FieldElement is mathematically less than or equal to
+        * another.
+        * 
+        * @param val
+        * @return true if this FieldElement is less than or equal to val, false
+        *         otherwise
+        */
+
+       public boolean le(FieldElement val) {
+               return this.lt(val) || this.equals(val);
+       }
+
+       /**
+        * Checks whether this FieldElement is mathematically greater than or equal
+        * to another.
+        * 
+        * @param val
+        * @return true if this FieldElement is greater than or equal to val, false
+        *         otherwise
+        */
+
+       public boolean ge(FieldElement val) {
+               return this.gt(val) || this.equals(val);
+       }
+
+       /**
+        * Returns an instance of this FieldElement to be used in computing mean and
+        * other values.
+        * 
+        * @param dval
+        *            the value to use
+        * @return instance
+        */
+
+       public abstract FieldElement instance(double dval);
+
+       /**
+        * Uses a given double value that was randomly generated before to create a
+        * FieldElement. By default this method just calls instance(dval) but in
+        * some cases something else might be sensible. This method is used by
+        * LinAlgFactory.
+        * 
+        * @param dval
+        * @return mapped value
+        */
+
+       /**
+        * This generates a uniformly distributed random value [0..1[ .
+        */
+       protected FieldElement randomValue(Random random) {
+               return this.instance(random.nextDouble());
+       }
+
+       /**
+        * This generates a normally distributed random value N(0, 1) .
+        * 
+        */
+       protected FieldElement gaussianRandomValue(Random random) {
+               return this.instance(random.nextGaussian());
+       }
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/FieldP.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/FieldP.java
new file mode 100644 (file)
index 0000000..774c393
--- /dev/null
@@ -0,0 +1,1110 @@
+package JLinAlg;\r
+\r
+import java.lang.ref.WeakReference;\r
+import java.math.BigDecimal;\r
+import java.math.BigInteger;\r
+import java.util.HashMap;\r
+import java.util.Random;\r
+\r
+/**\r
+ * This class represents an element of the modulo p field Fp (i.e. the Galois field GF(p))\r
+ * where p is prime. Fp is a field like any other field\r
+ * but there is no order that respects addition.\r
+ *  \r
+ * @author Andreas Lochbihler\r
+ */\r
+/* This is only a wrapper class for the different implementations for FieldPAbstract\r
+ * depending on the magnitude of p.\r
+ * */\r
+public class FieldP extends FieldElement {\r
+\r
+       /** for all primes p less than PRIME_SEPARATION_BOUNDARY long\r
+        * variables are sufficient for computation whereas above BigInteger\r
+        * must be used. */\r
+       private static final long PRIME_SEPARATION_BOUNDARY = 3037000500l;\r
+       private static final BigInteger PRIME_SEPARATION_BOUNDARY_BIG =\r
+               BigInteger.valueOf(PRIME_SEPARATION_BOUNDARY);\r
+\r
+       /** for all Fp with p &lt;= inversesLookupTableBoundary inverses are stored\r
+        * in a lookup table of size p , for bigger fields inverses are stored with the\r
+        * element. It is assumed that inversesLookupTableBoundary < PRIME_SEPARATION_BOUNDARY */\r
+       private static long inversesLookupTableBoundary = 65521;\r
+\r
+       /** Reference to the implementation of this element */\r
+       private FieldPAbstract element;\r
+\r
+       /**\r
+        * Creates a new FieldP object representing the element (equivalence class) of\r
+        * the field Fp which contains value. Depending on the magnitude of p,\r
+        * the right implementations is automatically chosen. See setInversesLookupTableBoundary\r
+        * for tuning options. \r
+        * @param value A representative of the equivalence class to create\r
+        * @param p The positive prime specifying the number of elements in Fp.\r
+        */\r
+       public FieldP(long value, long p) {\r
+               if (!isPrime(p)) {\r
+                       throw new IllegalArgumentException("p = " + p + " is not a prime.");\r
+               }\r
+\r
+               if (p <= inversesLookupTableBoundary) {\r
+                       element = FieldPLongLookup.instance(value, p);\r
+               } else if (p < PRIME_SEPARATION_BOUNDARY) {\r
+                       element = new FieldPLongNoLookup(value, p);\r
+               } else {\r
+                       element =\r
+                               new FieldPBig(BigInteger.valueOf(value), BigInteger.valueOf(p));\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Creates a new FieldP object representing the element (equivalence class) of\r
+        * the field FP which contains value. Depending on the magnitude of p,\r
+        * the right implementation is automatically chosen, i.e., if p is small enough\r
+        * to do all computations using long, this implementation will be chosen.\r
+        * @param value A representative of the equivalence class to create.\r
+        * @param p The positive prime specifying the number of elements in Fp.\r
+        */\r
+       public FieldP(BigInteger value, BigInteger p) {\r
+               if (!isPrime(p)) {\r
+                       throw new IllegalArgumentException("p = " + p + " is not a prime.");\r
+               }\r
+\r
+               if (p.compareTo(PRIME_SEPARATION_BOUNDARY_BIG) < 0) {\r
+                       long pL = p.longValue();\r
+                       long vL = value.mod(p).longValue();\r
+\r
+                       if (pL <= inversesLookupTableBoundary) {\r
+                               element = FieldPLongLookup.instance(vL, pL);\r
+                       } else {\r
+                               element = new FieldPLongNoLookup(vL, pL);\r
+                       }\r
+               } else {\r
+                       element = new FieldPBig(value, p);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Creates a new wrapper object with reference to element. For internal use only.\r
+        * @param element The element to be represented by the new wrapper object.\r
+        */\r
+       private FieldP(FieldPAbstract element) {\r
+               this.element = element;\r
+       }\r
+\r
+       /**\r
+        * Adds this element to val and returns the new element of Fp.\r
+        * @param val The second operand. Must be of the same field Fp.\r
+        * @return The element that is the sum of this and val.\r
+        */\r
+       public FieldElement add(FieldElement val) {\r
+               return new FieldP((FieldPAbstract) element.add(((FieldP) val).element));\r
+       }\r
+\r
+       /**\r
+        * Multiplies this element with val and returns the new element of Fp.\r
+        * @param val The second operand. Must be of the same field Fp.\r
+        * @return The element that is the sum of this and val.\r
+        */\r
+       public FieldElement multiply(FieldElement val) {\r
+               return new FieldP(\r
+                       (FieldPAbstract) element.multiply(((FieldP) val).element));\r
+       }\r
+\r
+       /**\r
+        * Returns the zero element of this field Fp.\r
+        * @return The zero element of this field Fp.\r
+        */\r
+       public FieldElement zero() {\r
+               return new FieldP((FieldPAbstract) element.zero());\r
+       }\r
+\r
+       /**\r
+        * Returns the one element of this field Fp.\r
+        * @return The one element of this field Fp.\r
+        */\r
+       public FieldElement one() {\r
+               return new FieldP((FieldPAbstract) element.one());\r
+       }\r
+\r
+       /**\r
+        * Returns the additive inverse of this in the field Fp.\r
+        * @return The additive inverse of this in the field Fp.\r
+        */\r
+       public FieldElement negate() {\r
+               return new FieldP((FieldPAbstract) element.negate());\r
+       }\r
+\r
+       /**\r
+        * Returns the multiplicative inverse of this in the field Fp.\r
+        * @return The multiplicative inverse of this in the field Fp.\r
+        */\r
+       public FieldElement invert() {\r
+               return new FieldP((FieldPAbstract) element.invert());\r
+       }\r
+\r
+       /**\r
+        * Compares this element with another element. o must be a instance of\r
+        * FieldP and its field must have the same number of elements as this' one.\r
+        * A element of Fp is considered to be smaller than a other element if and\r
+        * only if its smallest nonnegative representative is smaller than the other's one.\r
+        * @param o The object to compare to. Must be a instance of FieldP and of the same\r
+        *          field Fp as this.\r
+        * @return &lt; 0 if this is smaller than o,\r
+        *         = 0 if this is equal to o (in the sense of equals),\r
+        *         &gt; 0 if this is bigger than o\r
+        */\r
+       public int compareTo(Object o) {\r
+               return element.compareTo(((FieldP) o).element);\r
+       }\r
+\r
+       /**\r
+        * Computes the element for the integral part of dval\r
+        * @param dval The value to use\r
+        * @return The element representing the integral part of dval\r
+        */\r
+       public FieldElement instance(double dval) {\r
+               return element.instance(dval);\r
+       }\r
+\r
+       /**\r
+        * Maps a double value (0<=dval<1) to a element of FieldP<BR>\r
+        * <STRONG>Note!</STRONG> Normal Distribution Issue<BR> \r
+        * In case of a normally distributed double as in \r
+        * LinAlgFactory.gaussianRandomValue() it won't give you \r
+        * the right distribution.\r
+        * @param random The random value to be mapped\r
+        * @return a random element corresponding to dval.nextDouble().\r
+        */\r
+       protected FieldElement randomValue(Random random) {\r
+               return new FieldP((FieldPAbstract) element.randomValue(random));\r
+       }\r
+\r
+       protected FieldElement gaussianRandomValue(Random random) {\r
+               return new FieldP((FieldPAbstract) element.randomValue(random));\r
+       }\r
+\r
+       /**\r
+        * Returns true if and only if this and o represent the same element of the same field.\r
+        * @param fe The element to compare to.\r
+        * @return True if and only if this and o are the same equivalence class of the same field.\r
+        */\r
+       public boolean equals(FieldElement fe) {\r
+               return element.equals(((FieldP) fe).element);\r
+       }\r
+\r
+       /**\r
+        * Returns a string representation of this element of the form vmp where\r
+        * v is the smallest non-negative representant of the equivalence class in the\r
+        * field with p elements.\r
+        * @return The string representation of this element.  \r
+        */\r
+       public String toString() {\r
+               return element.toString();\r
+       }\r
+\r
+       /**\r
+        * Returns true if and only if this and o represent the same element of the same field.\r
+        * @param o The element to compare to.\r
+        * @return True if and only if this and o are the same equivalence class of the same field.\r
+        */\r
+       public boolean equals(Object o) {\r
+               return element.equals(((FieldP) o).element);\r
+       }\r
+\r
+       /**\r
+        * Returns the number n which decides whether to store inverses in a lookup table\r
+        * (for fields with less or equal than n elements) or with the elements (otherwise)\r
+        * @return The number inversesLookupTableBoundary\r
+        */\r
+       public static long getInversesLookupTableBoundary() {\r
+               return inversesLookupTableBoundary;\r
+       }\r
+\r
+       /**\r
+        * This methods sets the boundary on the elements of Fp above which all inverses\r
+        * are stored with the elements and therefore may be computed several times instead\r
+        * of storing them in a lookup table. When using a lookup table for the inverses\r
+        * the inverse of a element will be automatically computed at creation time and stored\r
+        * in the table. If you are sure you will never need division it might be faster to\r
+        * set the boundary lower than the number of elements in your field BEFORE creating the\r
+        * first element of it. \r
+        * \r
+        * WARNING: If you change this boundary AFTER you have instantiated at least one\r
+        * element of Fp where p is less than Integer.MAX_VALUE, all existing elements\r
+        * which have not used the lookup-table won't use it either afterwards. Moreover,\r
+        * any new elements generated from these by unary operations or by binary operations\r
+        * where they from the first operand won't use it either. Similarily all elements which\r
+        * have used the lookup table and all elements generated from them in the same way will\r
+        * still use the lookup table. The memory allocated to the lookup table will not be freed\r
+        * before all elements using the lookup table are removed. Lookup tables are separate for\r
+        * each Fp. \r
+        * \r
+        * @param boundary The number n of elements in Fp above which no lookup table should be\r
+        * used.\r
+        */\r
+       public static void setInversesLookupTableBoundary(long boundary) {\r
+               inversesLookupTableBoundary = Math.min(Integer.MAX_VALUE, boundary);\r
+       }\r
+\r
+       /**\r
+        * Tuning option. If you expect to need most of the inverses in Fp, i.e. want to\r
+        * divide by most of the elements, then this speeds the division up by computing\r
+        * the inverses ahead.\r
+        * This method only computes the inverse if there is a lookup table for the inverses.\r
+        */\r
+       public void computeAllInverses() {\r
+               element.computeAllInverses();\r
+       }\r
+\r
+       /**\r
+        * Checks for primality of p. Intended to be used for checking the primality\r
+        * requirement of p in a Fp field. Not implemented yet, it is left up to the\r
+        * user to ensure the primality of p.\r
+        * @param p The number to check for primality\r
+        * @return For the time being, 2 and all odd numbers are considered prime\r
+        */\r
+       static boolean isPrime(long p) {\r
+               return (p == 2) || (p % 2 == 1);\r
+       }\r
+\r
+       /**\r
+        * Checks for primality of p. Intended to be used for checking the primality\r
+        * requirement of p in a Fp field. Not implemented yet, it is left up to the\r
+        * user to ensure the primality of p.\r
+        * @param p The number to check for primality\r
+        * @return For the time being, every number is considered a prime\r
+        */\r
+       private static boolean isPrime(BigInteger p) {\r
+               return true;\r
+       }\r
+\r
+}\r
+\r
+/**\r
+ * This class defines the abstract class for actual implementations of FieldP.\r
+ * \r
+ * IMPORTANT: This class and its subclasses make use of the concept of immutability\r
+ * of objects. If you make changes or subclass these classes, ensure immutability\r
+ * or overwrite the methods affected.\r
+ * \r
+ * @author Andreas Lochbihler\r
+ */\r
+abstract class FieldPAbstract extends FieldElement {\r
+       /**\r
+        * Creates a new element of Fp which is the equivalence class of val.\r
+        * @param val A representant of the equivalence class to create. val does not\r
+        * have to be the smallest nonnegative representant.\r
+        * @return The equivalence class containing val in Fp.\r
+        */\r
+       public abstract FieldPAbstract instance(long val);\r
+\r
+       /**\r
+        * Tuning option. If you expect to need most of the inverses in Fp, i.e. want to\r
+        * divide by most of the elements, then this speeds the division up by computing\r
+        * the inverses ahead. If the implementation does not support computing inverses\r
+        * ahead of the point of time when they are needed, this method is supposed to\r
+        * do nothing.\r
+        */\r
+       public abstract void computeAllInverses();\r
+\r
+       /**\r
+        * Returns the element that is the equivalence class of this field containing\r
+        * the integral part of val as a representative.\r
+        * @param val Its integral part specifies the equivalence class to return.\r
+        * @return The equivalence class containing the integral part of val. \r
+        */\r
+       public FieldElement instance(double val) {\r
+               return instance((long) val);\r
+       }\r
+\r
+}\r
+\r
+/**\r
+ * This class implements the operations in Fp where p &lt; PRIME_SEPARATION_BOUNDARY.\r
+ * All computations can be done using long variables.\r
+ * \r
+ * IMPORTANT: This class and its subclasses make use of the concept of immutability\r
+ * of objects. If you make changes or subclass these classes, ensure immutability\r
+ * or overwrite the methods affected.\r
+ * \r
+ * @author Lochbihler Andreas\r
+ */\r
+abstract class FieldPLong extends FieldPAbstract {\r
+\r
+       /** The least non-negative representant of the equivalence class */\r
+       protected long value;\r
+\r
+       /** The prime speicifying the number of elements in the field */\r
+       protected long p;\r
+\r
+       /**\r
+        * Returns a new element of the field Fp. The element is the\r
+        * equivalence class containing value.\r
+        * @param value The new element is the equivalence class of value\r
+        * @param p The number of elements in the Field. p must be prime.\r
+        *          It is up to the user to ensure that p^2<Long.MAX_VALUE otherwise\r
+        *          overflow problems may occur\r
+        */\r
+       protected FieldPLong(long value, long p) {\r
+               if (!FieldP.isPrime(p)) {\r
+                       throw new IllegalArgumentException(\r
+                               "p = "\r
+                                       + p\r
+                                       + " must be a prime in order to ensure the field property");\r
+               }\r
+\r
+               this.value = value;\r
+               this.p = p;\r
+               this.normalize();\r
+       }\r
+\r
+       /**\r
+        * Generates a new zero element of Fp. Only for internal use within this class.\r
+        * No parameter checking is done. Assumes that there is already at least one\r
+        * element of Fp in memory.\r
+        * @param p The number of elements in the field. Must be prime.\r
+        */\r
+       protected FieldPLong(long p) {\r
+               this.p = p;\r
+       }\r
+\r
+       /**\r
+        * Calculates the sum of this element and another one from the same\r
+        * field.\r
+        *\r
+        * @param val The other element to add\r
+        * @return The sum of both elements\r
+        * @throws IllegalArgumentException Thrown if you are trying to add elements from\r
+        *         different fields Fp.\r
+        */\r
+       public FieldElement add(FieldElement val) throws IllegalArgumentException {\r
+               FieldPLong op = (FieldPLong) val;\r
+               if (op.p == this.p) {\r
+                       return instance(this.value + op.value);\r
+               } else {\r
+                       throw new IllegalArgumentException(\r
+                               val\r
+                                       + " is from a different Fp than "\r
+                                       + this\r
+                                       + "! You cannot add them.");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Calculates the product of this element and another one from the same\r
+        * field.\r
+        *\r
+        * @param val The other element to multiply\r
+        * @return The product of both elements\r
+        * @throws IllegalArgumentException Thrown if you are trying to multiply elements from\r
+        *         different fields Fp.\r
+        */\r
+       public FieldElement multiply(FieldElement val)\r
+               throws IllegalArgumentException {\r
+               FieldPLong op = (FieldPLong) val;\r
+               if (op.p == this.p) {\r
+                       return instance(this.value * op.value);\r
+               } else {\r
+                       throw new IllegalArgumentException(\r
+                               val\r
+                                       + " is from a different Fp than "\r
+                                       + this\r
+                                       + "! You cannot multiply them.");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns the zero element of the field Fp\r
+        * @return The zero element of the field Fp\r
+        */\r
+       public FieldElement zero() {\r
+               return instance(0);\r
+       }\r
+\r
+       /**\r
+        * Returns the one element of the field Fp\r
+        * @return The one element of the field Fp\r
+        */\r
+       public FieldElement one() {\r
+               return instance(1);\r
+       }\r
+\r
+       /**\r
+        * Computes the additive inverse\r
+        * @return The additive inverse\r
+        */\r
+       public FieldElement negate() {\r
+               return instance(-value);\r
+       }\r
+\r
+       /**\r
+        * Returns a string representation of the element. The string representation\r
+        * consists of the value of the smallest non-\r
+        * negative representant of the equivalence class in 10-adic, the letter m\r
+        * and the number of elements in the field in 10-adic.\r
+        * @return The string representation of the element.\r
+        */\r
+       public String toString() {\r
+               return value + "m" + p;\r
+       }\r
+\r
+       /**\r
+        * Compares this element with another element of the same field Fp.\r
+        * Note: This order does not respect addition or multiplication!\r
+        * @param o The element to compare to\r
+        * @return -1, if this is less, 0, if they are equal, 1, if this is bigger\r
+        */\r
+       public int compareTo(Object o) {\r
+               FieldPLong par = (FieldPLong) o;\r
+               if (this.p == par.p) {\r
+                       long diff = this.value - par.value;\r
+                       return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));\r
+               } else {\r
+                       throw new IllegalArgumentException(\r
+                               o\r
+                                       + " is from a differend field than "\r
+                                       + this\r
+                                       + "! You cannot compare them");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Normalizes the value of the element of Fp.\r
+        * This means that value will contain the least non-negative\r
+        * representative of the equivalence class in which value was at call time.\r
+        */\r
+       public void normalize() {\r
+               this.value = FieldPLong.normalize(this.value, this.p);\r
+       }\r
+\r
+       /**\r
+        * Normalizes val with respect to p.\r
+        * This means, it computes 0<=r<p such that p divides v-r\r
+        * @param val The value to normalize\r
+        * @param p The number of elements in Fp\r
+        * @return The normalized value of val in Fp.\r
+        */\r
+       protected static long normalize(long val, long p) {\r
+               val = val % p;\r
+               if (val < 0) {\r
+                       val += p;\r
+               }\r
+               return val;\r
+       }\r
+\r
+       /**\r
+        * Computes the multiplicative inverse of val in Fp\r
+        * @param val The smallest non-negative representative of the equivalence class to invert in Fp.\r
+        * @return The multiplicative inverse of val in Fp, if it exists.\r
+        */\r
+       protected long computeInverse(long val) {\r
+               return FieldPLong.computeInverse(val, this.p);\r
+       }\r
+\r
+       /**\r
+        * Computes the inverse in Fp.\r
+        * @param val The value whose inverse is to be computed\r
+        * @param p The number of elements in the field.\r
+        * @return The inverse of val in Fp.\r
+        */\r
+       protected static long computeInverse(long val, long p) {\r
+               long a = p;\r
+               long b = val;\r
+\r
+               long w = 1;\r
+               long x = 1;\r
+               long y = 0;\r
+               long z = 0;\r
+\r
+               long r = 0;\r
+               long q = 0;\r
+\r
+               long new_z, new_w;\r
+\r
+               // The invariant is x*p + y*value = a and z*p + w*value = b\r
+               while (b != 0) {\r
+                       r = a % b;\r
+                       q = a / b;\r
+\r
+                       // swap variables\r
+                       a = b;\r
+                       b = r;\r
+\r
+                       new_z = x - q * z;\r
+                       new_w = y - q * w;\r
+                       x = z;\r
+                       y = w;\r
+                       z = new_z;\r
+                       w = new_w;\r
+               }\r
+\r
+               if (a != 1) {\r
+                       throw new InvalidOperationException(\r
+                               val + " is not invertible in F" + p);\r
+               } else {\r
+                       // normalize y\r
+                       while (y < 0) {\r
+                               y += p;\r
+                       }\r
+                       return y;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Maps a double value (0<=dval<1) to a element of FieldP\r
+        * @param dval: The random value to be mapped\r
+        * @return a random element corresponding to dval.\r
+        */\r
+       public FieldElement randomValue(Random random) {\r
+               return instance(p * random.nextDouble());\r
+       }\r
+\r
+}\r
+\r
+/**\r
+  * This class implements an element of Fp using a static lookup table for storing\r
+  * multiplicative inverses. This lookup table for Fp is kept in memory as long as there is\r
+  * at least one element of Fp in memory. If at some point no element of Fp can be\r
+  * strongly referenced it is up to the garbage collector to remove the lookup table\r
+  * for Fp.\r
+  * \r
+  * IMPORTANT: This class and its subclasses make use of the concept of immutability\r
+  * of objects. It is somewhat like a singleton except that there may be p objects of it, each\r
+  * with a different attribute value.\r
+  * If you make changes or subclass these classes, ensure immutability\r
+  * or overwrite the methods affected, i.e. constructor, instance, enterInverses,\r
+  * equals, clone.\r
+  * \r
+  * @author Andreas Lochbihler\r
+  */\r
+class FieldPLongLookup extends FieldPLong {\r
+\r
+       /**\r
+        * Maps from Long(p) objects to WeakReference objects referencing\r
+        * FieldPLongLookup[] arrays of length (p-1).\r
+        * The j-th entry contains the multiplicative inverse of j if already computed\r
+        * otherwise it is 0. The mapping has not to be right total.\r
+        */\r
+       private static HashMap inverses = new HashMap();\r
+\r
+       /**\r
+        * Reference to the lookup table of inverses for Fp.\r
+        * Must always be initialized. If the inverse of i is in the table and ist j,\r
+        * then there must also be inverseTable[j] = i and inverseTable[p-i]=p-j and\r
+        * inverseTable[p-j]=p-i.\r
+        * inverseTable[0] stores the zero element,\r
+        * inverseTable[1] stores the one element.\r
+        */\r
+       private FieldPLongLookup[] inverseTable;\r
+\r
+       /**\r
+        * Generates a new element of Fp. Only for internal use within this class.\r
+        * No parameter checking is done. \r
+        * @param value The new element is the equivalence class of value\r
+        * @param p The number of elements in the field. Must be prime.\r
+        * @param inverseTable The table of inverses for this field Fp\r
+        */\r
+       private FieldPLongLookup(\r
+               long value,\r
+               long p,\r
+               FieldPLongLookup[] inverseTable) {\r
+               super(p);\r
+               this.value = value;\r
+               this.inverseTable = inverseTable;\r
+       }\r
+\r
+       /**\r
+        * Computes the multiplicative inverse\r
+        * @return The multiplicative inverse\r
+        * @throws DivisionByZeroException Thrown if there is no inverse\r
+        *         (i.e. this element is 0 or value is not relatively prime to p,)\r
+        */\r
+       public FieldElement invert() throws DivisionByZeroException{\r
+               if (this.isZero()) {\r
+                       throw new DivisionByZeroException("Tried to invert zero.");\r
+               } else {\r
+                       /* The inverse has already been computed at creation time */\r
+                       return inverseTable[(int) value];\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns this field element since each element may exist only once!\r
+        * @return The field element\r
+        */\r
+       public Object clone() {\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Check for equality of this with o. Two elements are equal if they represent the same\r
+        * equivalence class in the same field Fp. \r
+        * @return True if and only if this is equal to o in the above sense.\r
+        */\r
+       public boolean equals(Object o) {\r
+               return (this == o);\r
+       }\r
+\r
+       /**\r
+        * Computes all the inverses for this field Fp and stores them in the\r
+        * lookup table.\r
+        */\r
+       public void computeAllInverses() {\r
+               if (p > 2) {\r
+                       // compute 2 separately\r
+                       if (inverseTable[2] == null) {\r
+                               long q = (p - 1) / 2;\r
+\r
+                               enterInverses(2, q);\r
+\r
+                               long a = 2;\r
+\r
+                               long q1 = q;\r
+                               while (q > 0 && a < q1) {\r
+                                       if (q % 2 == 0) {\r
+                                               q = q >> 1;\r
+                                               a = a << 1;\r
+                                       } else {\r
+                                               q = (q + p) / 2; // p is odd since p is a prime > 2\r
+                                               a = a << 1;\r
+                                       }\r
+                                       enterInverses(a, q);\r
+                               }\r
+                       }\r
+\r
+                       long a = 3;\r
+                       long q, a1;\r
+                       while (a < p) {\r
+                               if (inverseTable[(int) a] == null) {\r
+                                       q = computeInverse(a);\r
+                                       enterInverses(a, q);\r
+                                       a1 = a;\r
+                                       while (q % a1 == 0) {\r
+                                               q /= a1;\r
+                                               a = (a * a1) % p;\r
+                                               enterInverses(a, q);\r
+                                       }\r
+                               }\r
+                               a++;\r
+                       }\r
+\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Enters the multiplicative inverses of a, b, (p-a) and (p-b) in the lookup table. \r
+        * @param a The inverse of b\r
+        * @param b The inverse of a\r
+        */\r
+       private void enterInverses(long a, long b) {\r
+               if (inverseTable[(int) a] == null) {\r
+                       enterInverses(a, b, p, inverseTable);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Enters the multiplicative inverses of a, b, (p-a) and (p-b) in the lookup table.\r
+        * @param a The inverse of b wrt p\r
+        * @param b The inverse of a wrt p\r
+        * @param p The number of elements in the field.\r
+        * @param inverseTable The inverse lookup table.\r
+        */\r
+       private static void enterInverses(\r
+               long a,\r
+               long b,\r
+               long p,\r
+               FieldPLongLookup[] inverseTable) {\r
+\r
+               inverseTable[(int) a] = new FieldPLongLookup(b, p, inverseTable);\r
+               if (a != b) {\r
+                       inverseTable[(int) b] = new FieldPLongLookup(a, p, inverseTable);\r
+                       if (inverseTable[(int) (p - a)] == null) {\r
+                               inverseTable[(int) (p - a)] =\r
+                                       new FieldPLongLookup(p - b, p, inverseTable);\r
+                               inverseTable[(int) (p - b)] =\r
+                                       new FieldPLongLookup(p - a, p, inverseTable);\r
+                       }\r
+               } else if (inverseTable[(int) (p - b)] == null) {\r
+                       inverseTable[(int) (p - b)] =\r
+                               new FieldPLongLookup(p - a, p, inverseTable);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Creates a new element of Fp which is the equivalence class of val.\r
+        * @param val A representant of the equivalence class to create. val does not\r
+        * have to be the smallest nonnegative representant.\r
+        * @return The equivalence class containing val in Fp.\r
+        */\r
+       public FieldPAbstract instance(long val) {\r
+               return instance(val, this.p, this.inverseTable);\r
+       }\r
+\r
+       /**\r
+        * Returns the element representing the equivalence class in which val is of the field Fp.\r
+        * If this is the first element of Fp to be created, the lookup table will be\r
+        * initialized. \r
+        * @param val The value specifying the equivalence class to return\r
+        * @param p The number of elements in Fp\r
+        * @return The equivalence class containing val in Fp.\r
+        */\r
+       public static FieldPAbstract instance(long val, long p) {\r
+               /* Does the table of inverses exist? */\r
+               Long pL = new Long(p);\r
+               WeakReference wref = (WeakReference) inverses.get(pL);\r
+\r
+               FieldPLongLookup[] inverseTable;\r
+\r
+               if ((wref == null)\r
+                       || ((inverseTable = (FieldPLongLookup[]) wref.get()) == null)) {\r
+                       // No -> create a new one\r
+                       inverseTable = new FieldPLongLookup[(int) p];\r
+\r
+                       /* add the zero element */\r
+                       inverseTable[0] = new FieldPLongLookup(0, p, inverseTable);\r
+\r
+                       // fill automatically inverses of 1 and (p-1)\r
+                       inverseTable[1] = new FieldPLongLookup(1, p, inverseTable);\r
+                       inverseTable[(int) p - 1] =\r
+                               new FieldPLongLookup(p - 1, p, inverseTable);\r
+\r
+                       // store for further usage\r
+                       inverses.put(pL, new WeakReference(inverseTable));\r
+               }\r
+\r
+               return instance(val, p, inverseTable);\r
+       }\r
+\r
+       /**\r
+        * Returns the element of Fp which val is in.\r
+        * @param val The value specifying the equivalence class to return\r
+        * @param p The number of elements of Fp\r
+        * @param inverseTable The lookup table for multiplicative inverses in Fp\r
+        * @return The equivalence class in which val is.\r
+        */\r
+       private static FieldPAbstract instance(\r
+               long val,\r
+               long p,\r
+               FieldPLongLookup[] inverseTable) {\r
+               val = normalize(val, p);\r
+\r
+               FieldPLongLookup inverseFP = inverseTable[(int) val];\r
+               FieldPLongLookup element;\r
+               if (inverseFP == null) {\r
+                       long inverse = computeInverse(val, p);\r
+                       enterInverses(val, inverse, p, inverseTable);\r
+                       element = inverseTable[(int) inverse];\r
+               } else {\r
+                       element = inverseTable[(int) inverseFP.value];\r
+               }\r
+               return element;\r
+       }\r
+\r
+}\r
+\r
+/**\r
+ * This class implements an element of Fp where p is less than\r
+ * FieldP.PRIME_SEPARATIN_BOUNDARY. Inverses are computed on demand and then\r
+ * stored with the element. So if generating more than one object of the same\r
+ * element of Fp then the computation of the multiplicative inverse may have\r
+ * to be performed multiple times.\r
+ * \r
+ * For small p it is recommended to use the lookup table version FieldPLongLookup. \r
+ * \r
+ * @author Andreas Lochbihler\r
+ */\r
+class FieldPLongNoLookup extends FieldPLong {\r
+\r
+       /**\r
+        * Store the inverse of this element in Fp, if already computed, otherwise null.\r
+        */\r
+       private FieldPLongNoLookup inverse;\r
+\r
+       /**\r
+        * Create a new element of Fp being the equivalence class of value\r
+        * @param value A representant of the equivalence class to be created.\r
+        * @param p The number of elements in Fp. Must be prime.\r
+        */\r
+       protected FieldPLongNoLookup(long value, long p) {\r
+               super(value, p);\r
+       }\r
+\r
+       /**\r
+        * Generates a new zero element of Fp. Only for internal use within this class.\r
+        * No parameter checking is done. Assumes that there is already at least one\r
+        * element of Fp in memory.\r
+        * @param p The number of elements in the field. Must be prime.\r
+        */\r
+       protected FieldPLongNoLookup(long p) {\r
+               super(p);\r
+       }\r
+\r
+       /**\r
+        * Generates a new element of Fp being the equivalence class of value. Only\r
+        * for internal use within this class. No parameter checking is done.\r
+        * Assumes that there is already at least one element of Fp in memory.\r
+        * @param value The smallest nonnegative representant of the desired equivalence\r
+        *              class\r
+        * @param p The number of elements in the field. Must be prime.\r
+        * @param inverse The inverse of value in Fp. null if unknown.\r
+        */\r
+       protected FieldPLongNoLookup(\r
+               long value,\r
+               long p,\r
+               FieldPLongNoLookup inverse) {\r
+               super(p);\r
+               this.value = value;\r
+               this.inverse = inverse;\r
+       }\r
+\r
+       /**\r
+        * Creates a new element of Fp which is the equivalence class of val.\r
+        * @param val A representant of the equivalence class to create. val does not\r
+        * have to be the smallest nonnegative representant.\r
+        * @return The equivalence class containing val in Fp.\r
+        */\r
+       public FieldPAbstract instance(long val) {\r
+               FieldPLongNoLookup res = new FieldPLongNoLookup(this.p);\r
+               res.value = val;\r
+               res.normalize();\r
+               return res;\r
+       }\r
+\r
+       /**\r
+        * Computes the multiplicative inverse\r
+        * @return The multiplicative inverse\r
+        * @throws DivisionByZeroException Thrown if there is no inverse\r
+        *         (i.e. this element is 0 or value is not relatively prime to p,)\r
+        */\r
+       public FieldElement invert() {\r
+               if (this.isZero()) {\r
+                       throw new DivisionByZeroException("Tried to invert zero.");\r
+               }\r
+\r
+               if (inverse == null) {\r
+                       inverse = new FieldPLongNoLookup(computeInverse(value), p, this);\r
+               }\r
+\r
+               return inverse;\r
+       }\r
+\r
+       /**\r
+        * Supposed to compute all inverses. But since they are not stored in a\r
+        * lookup-table, do nothing.\r
+        */\r
+       public void computeAllInverses() {\r
+       }\r
+\r
+}\r
+\r
+/**\r
+ * This class implements an element of Fp where p can be arbitrarily big by\r
+ * using BigIntegers.\r
+ * \r
+ * @author Andreas Lochbihler\r
+ */\r
+class FieldPBig extends FieldPAbstract {\r
+\r
+       /**\r
+        * The smallest nonnegative representant of the equivalence class in Fp.\r
+        */\r
+       private BigInteger value;\r
+\r
+       /**\r
+        * If already computed, the multiplicative inverse of value. null otherwise\r
+        */\r
+       private FieldPBig inverse;\r
+\r
+       /**\r
+        * The number of elements in Fp. Must be a prime.\r
+        */\r
+       private BigInteger p;\r
+\r
+       /**\r
+        * Constructs a new element of Fp which is the equivalence class containing\r
+        * value.\r
+        * @param value Any representant of the desired equivalence class\r
+        * @param p The number of elements in Fp. Must be prime.\r
+        */\r
+       FieldPBig(BigInteger value, BigInteger p) {\r
+               this.value = value;\r
+               this.p = p;\r
+               normalize();\r
+       }\r
+\r
+       /**\r
+        * Creates a not-valid element of Fp (i.e. value is set to null). Only for\r
+        * internal use.\r
+        * @param p The p in Fp.\r
+        */\r
+       private FieldPBig(BigInteger p) {\r
+               this.p = p;\r
+       }\r
+\r
+       /**\r
+        * Creates a new element of Fp being the equivalence class of value and\r
+        * having the multiplicative inverse inverse. No parameter checking.\r
+        * Only for internal use.\r
+        * @param value The smallest nonnegative representant of the desired equivalence class \r
+        * @param p The number of elements in Fp\r
+        * @param inverse The multiplicative inverse of value.\r
+        */\r
+       private FieldPBig(BigInteger value, BigInteger p, FieldPBig inverse) {\r
+               this.value = value;\r
+               this.p = p;\r
+               this.inverse = inverse;\r
+       }\r
+\r
+       /**\r
+        * Returns the sum of this and val.\r
+        * @param val The other operand.\r
+        * @return The sum of this and val.\r
+        */\r
+       public FieldElement add(FieldElement val) {\r
+               FieldPBig op = (FieldPBig) val;\r
+               if (this.p.equals(op.p)) {\r
+                       return new FieldPBig(this.value.add(op.value), p);\r
+               } else {\r
+                       throw new IllegalArgumentException(\r
+                               val\r
+                                       + " is from a different field Fp than "\r
+                                       + this\r
+                                       + "! You cannot add them.");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns the product of this and val.\r
+        * @param val The other factor\r
+        * @return The product of this and val.\r
+        */\r
+       public FieldElement multiply(FieldElement val) {\r
+               FieldPBig op = (FieldPBig) val;\r
+               if (this.p.equals(op.p)) {\r
+                       return new FieldPBig(this.value.multiply(op.value), p);\r
+               } else {\r
+                       throw new IllegalArgumentException(\r
+                               val\r
+                                       + " is from a different field Fp than "\r
+                                       + this\r
+                                       + "! You cannot multiply them.");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns the zero element of the field Fp\r
+        * @return The zero element of the field Fp\r
+        */\r
+       public FieldElement zero() {\r
+               FieldPBig res = new FieldPBig(p);\r
+               res.value = BigInteger.ZERO;\r
+               return res;\r
+       }\r
+\r
+       /**\r
+        * Returns the one element of the field Fp\r
+        * @return The one element of the field Fp\r
+        */\r
+       public FieldElement one() {\r
+               FieldPBig res = new FieldPBig(p);\r
+               res.value = BigInteger.ONE;\r
+               res.inverse = res;\r
+               return res;\r
+       }\r
+\r
+       /**\r
+        * Computes the additive inverse\r
+        * @return The additive inverse\r
+        */\r
+       public FieldElement negate() {\r
+               return new FieldPBig(value.negate(), p);\r
+       }\r
+\r
+       /**\r
+        * Computes the multiplicative inverse\r
+        * @return The multiplicative inverse\r
+        * @throws DivisionByZeroException if this is zero.\r
+        */\r
+       public FieldElement invert()\r
+               throws DivisionByZeroException {\r
+               if (this.isZero()) {\r
+                       throw new DivisionByZeroException("Tried to invert zero.");\r
+               }\r
+               if (this.inverse == null) {\r
+                       this.inverse =\r
+                               new FieldPBig(this.value.modInverse(this.p), p, this);\r
+               }\r
+               return inverse;\r
+       }\r
+\r
+       /**\r
+        * Compares this element with another element of the same field Fp.\r
+        * Note: This order does not respect addition or multiplication!\r
+        * @param o The element to compare to\r
+        * @return -1, if this is less, 0, if they are equal, 1, if this is bigger\r
+        */\r
+       public int compareTo(Object o) {\r
+               FieldPBig par = (FieldPBig) o;\r
+               if (this.p.equals(par.p)) {\r
+                       return value.compareTo(par.value);\r
+               } else {\r
+                       throw new IllegalArgumentException(\r
+                               o\r
+                                       + " is from a differend field than "\r
+                                       + this\r
+                                       + "! You cannot compare them");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Creates a new element of Fp which is the equivalence class of val.\r
+        * @param val A representant of the equivalence class to create. val does not\r
+        * have to be the smallest nonnegative representant.\r
+        * @return The equivalence class containing val in Fp.\r
+        */\r
+       public FieldPAbstract instance(long value) {\r
+               return new FieldPBig(BigInteger.valueOf(value));\r
+       }\r
+\r
+       /**\r
+        * Computation of all inverses is not supported for FieldPBig. Since this is\r
+        * only a tuning option, it is transparent to the user.\r
+        */\r
+       public void computeAllInverses() {\r
+       }\r
+\r
+       /**\r
+        * Normalizes the value of the element of Fp.\r
+        * This means that value will contain the least non-negative\r
+        * representative of the equivalence class value was in at call time.\r
+        */\r
+       public void normalize() {\r
+               this.value = this.value.mod(this.p);\r
+       }\r
+\r
+       /**\r
+        * Returns a pseudo-random element. All elements are approximately equally probable.\r
+        * @return a pseudo-random element\r
+        */\r
+       public FieldElement randomValue() {\r
+               return new FieldPBig(\r
+                       new BigDecimal(this.p)\r
+                               .multiply(new BigDecimal(Math.random()))\r
+                               .toBigInteger(),\r
+                       this.p);\r
+       }\r
+\r
+       /**\r
+        * Maps a double value (0<=dval<1) to a element of FieldP\r
+        * @param dval: The random value to be mapped\r
+        * @return a random element corresponding to dval.\r
+        */\r
+       public FieldElement randomValue(Random random) {\r
+               return new FieldPBig(\r
+                       new BigDecimal(this.p)\r
+                               .multiply(new BigDecimal(random.nextDouble()))\r
+                               .toBigInteger(),\r
+                       this.p);\r
+       }\r
+\r
+}\r
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/GreaterThanComparator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/GreaterThanComparator.java
new file mode 100644 (file)
index 0000000..6d25b62
--- /dev/null
@@ -0,0 +1,11 @@
+package JLinAlg;
+
+
+// class to return FieldElement.one() or FieldElement.zero(), depending on 
+// result of FieldElement greater-than comparison
+class GreaterThanComparator extends FEComparator {
+
+       public boolean compare(FieldElement a, FieldElement b) {
+               return a.gt(b);
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/GreaterThanOrEqualToComparator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/GreaterThanOrEqualToComparator.java
new file mode 100644 (file)
index 0000000..14d4bb4
--- /dev/null
@@ -0,0 +1,11 @@
+package JLinAlg;
+
+
+// class to return FieldElement.one() or FieldElement.zero(), depending on 
+// result of FieldElement greater than or equal to comparison
+class GreaterThanOrEqualToComparator extends FEComparator {
+
+       public boolean compare(FieldElement a, FieldElement b) {
+               return a.ge(b);
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/Handbook.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/Handbook.java
new file mode 100644 (file)
index 0000000..26d7a1e
--- /dev/null
@@ -0,0 +1,629 @@
+/*
+  This file conains Java versions of the algorithms HQR, ELMHES, and BALANCE,
+  as presented in 
+  @Book{LinearAlgebraHandbook,
+    author =    {J.H. Wilkinson and C. Reinsch},
+    title =     {Handbook for Automatic Computation},
+    publisher =         {Springer-Verlag},
+    address =    {New York}
+    year =      {1971},
+    volume =    {II: Linear Algebra}
+  }
+
+  Author: Simon D. Levy
+
+*/
+
+package JLinAlg;
+
+class Handbook {
+
+       // Finds the eigenvalues of a real upper Hessenberg matrix, H,
+       // stored in the array h[0:n-1][0:n-1], and stores the real parts
+       // in the array wr[0:n-1] and the imaginary parts in the array
+       // wi[0:n-1].  macheps is the relative machine precision. The
+       // procedure fails if any eigenvalue takes more than 30
+       // iterations.
+       //
+       // Additional parameters:
+       //
+       //   cnt - gets number of iterations for each eigenvalue (negative
+       //         when two roots are found at once)
+       //
+       //   macheps - machine precision   
+       //
+       
+       /**
+        * Returns a complex vector containing the eigenvalues of a given matrix.
+        * Eigenvalues are computed as follows:<br><br>
+        *   (1) Balance the matrix <br>
+        *   (2) Reduce the balanced matrix to Hessenberg form <br>
+        *   (3) Run the QR algorithm on the Hessenberg matrix to obtain the 
+        *       eigenvalues.<br><br>
+        * The algorithms used for steps 1-3 are adapted from
+        *<PRE>&#064Book{LinearAlgebraHandbook,
+        *      author = {J.H. Wilkinson and C. Reinsch},
+        *      title =  {Handbook for Automatic Computation},
+        *      publisher = {Springer-Verlag},
+        *      address = {New York}
+        *      year = {1971},
+        *      volume = {II: Linear Algebra}
+        * }
+        * </PRE>
+        *
+        * @param a the matrix
+        * @return Vector of Complex
+        * @throws InvalidOperationException if theMatrix does not contain doubles
+        * @throws InvalidOperationException if theMatrix is not square
+        */
+       public static Vector eig(Matrix a) throws InvalidOperationException {
+               double[][] vals = null;
+               try {
+                       vals = doubleValues(a);
+               } catch (Exception e) {
+                       throw new InvalidOperationException("Matrix must contain only DoubleWrappers");
+               }
+
+               int m = a.getRows(), n = a.getCols();
+
+               if (m != n) {
+                       throw new InvalidOperationException("Matrix must be square");
+               }
+
+               double[] wr = new double[n];
+               double[] wi = new double[n];
+
+               int[] iint = new int[n];
+               int[] cnt = new int[n];
+               int[] lohi = new int[2];
+               double[] d = new double[n];
+
+               int radix = 2;
+               double macheps = 1e-20;
+
+               Handbook.balance(vals, lohi, d, n, radix);
+
+               Handbook.elmhes(vals, iint, n, lohi[0], lohi[1]);
+
+               Handbook.hqr(vals, wr, wi, cnt, n, macheps);
+
+               Complex[] entries = new Complex[n];
+
+               for (int i = 0; i < n; ++i) {
+                       entries[i] = new Complex(wr[i], wi[i]);
+               }
+
+               return new Vector(entries);
+       }
+       
+       protected static void hqr(
+               double[][] h,
+               double[] wr,
+               double[] wi,
+               int[] cnt,
+               int n,
+               double macheps) {
+
+               double t = 0;
+
+               while (n > 0) { // nextw 
+
+                       int its = 0, na = n - 1;
+
+                       while (true) { // nextit
+
+                               int l, m;
+
+                               // look for single small sub-diagonal element
+                               boolean found = false;
+                               for (l = n; l >= 2; l--) {
+                                       if (abs(get(h, l, l - 1))
+                                               <= macheps
+                                                       * (abs(get(h, l - 1, l - 1)) + abs(get(h, l, l)))) {
+                                               found = true;
+                                               break; // goto cont1
+                                       }
+                               }
+
+                               if (!found)
+                                       l = 1;
+
+                               // cont1
+
+                               double x = get(h, n, n);
+
+                               if (l == n) { // goto onew (one root found)
+                                       set(wr, n, x + t);
+                                       set(wi, n, 0);
+                                       n = na;
+                                       break; // goto nextw
+                               }
+
+                               double y = get(h, na, na), w = get(h, n, na) * get(h, na, n);
+
+                               if (l == na) { // goto twow (two roots found)
+                                       double p = (y - x) / 2, q = p * p + w;
+                                       y = sqrt(abs(q));
+                                       set(cnt, n, -its);
+                                       set(cnt, na, its);
+                                       x += t;
+                                       if (q > 0) { // real pair
+                                               if (p < 0)
+                                                       y = -y;
+                                               y = p + y;
+                                               set(wr, na, x + y);
+                                               set(wr, n, x - w / y);
+                                               set(wi, na, 0);
+                                               set(wi, n, 0);
+                                       } else { // complex pair
+                                               set(wr, na, x + p);
+                                               set(wr, n, x + p);
+                                               set(wi, na, y);
+                                               set(wi, n, -y);
+                                       }
+                                       n -= 2;
+                                       break; // goto nextw
+                               }
+
+                               if (its == 30) {
+                                       System.err.println("HQR failed after 30 iterations");
+                                       return; // goto fail
+                               }
+
+                               if (its == 10 || its == 20) { // form exceptional shift
+                                       t += x;
+                                       for (int i = 1; i <= n; ++i)
+                                               set(h, i, i, get(h, i, i) - x);
+                                       double s = abs(get(h, n, na)) + abs(get(h, na, n - 2));
+                                       x = y = 0.75 * s;
+                                       w = -0.4375 * s * s;
+                               }
+                               its++;
+
+                               // look for two consecutive sub-diagonal elements
+                               double p = 0, q = 0, r = 0, s = 0, z = 0;
+                               for (m = n - 2; m >= l; m--) {
+                                       z = get(h, m, m);
+                                       r = x - z;
+                                       s = y - z;
+                                       p = (r * s - w) / get(h, m + 1, m) + get(h, m, m + 1);
+                                       q = get(h, m + 1, m + 1) - z - r - s;
+                                       r = get(h, m + 2, m + 1);
+                                       s = abs(p) + abs(q) + abs(r);
+                                       p = p / s;
+                                       q = q / s;
+                                       r = r / s;
+                                       if (m == l)
+                                               break;
+                                       if (abs(get(h, m, m - 1)) * (abs(q) + abs(r))
+                                               <= macheps
+                                                       * abs(p)
+                                                       * (abs(get(h, m - 1, m - 1))
+                                                               + abs(z)
+                                                               + abs(get(h, m + 1, m + 1))))
+                                               break; // goto cont2
+                               }
+
+                               // cont2
+
+                               for (int i = m + 2; i <= n; ++i)
+                                       set(h, i, i - 2, 0);
+                               for (int i = m + 3; i <= n; ++i)
+                                       set(h, i, i - 3, 0);
+
+                               // double QR step involving rows l to n and columns m to n
+                               for (int k = m; k <= na; ++k) {
+                                       boolean notlast = (k != na);
+                                       if (k != m) {
+                                               p = get(h, k, k - 1);
+                                               q = get(h, k + 1, k - 1);
+                                               r = notlast ? get(h, k + 2, k - 1) : 0;
+                                               x = abs(p) + abs(q) + abs(r);
+                                               if (x == 0)
+                                                       break; // goto cont3
+                                               p /= x;
+                                               q /= x;
+                                               r /= x;
+                                       }
+                                       s = sqrt(p * p + q * q + r * r);
+                                       if (p < 0)
+                                               s = -s;
+                                       if (k != m)
+                                               set(h, k, k - 1, -s * x);
+                                       else if (l != m)
+                                               set(h, k, k - 1, -get(h, k, k - 1));
+                                       p += s;
+                                       x = p / s;
+                                       y = q / s;
+                                       z = r / s;
+                                       q /= p;
+                                       r /= p;
+
+                                       // row modification
+                                       for (int j = k; j <= n; ++j) {
+                                               p = get(h, k, j) + q * get(h, k + 1, j);
+                                               if (notlast) {
+                                                       p = p + r * get(h, k + 2, j);
+                                                       set(h, k + 2, j, get(h, k + 2, j) - p * z);
+                                               }
+                                               set(h, k + 1, j, get(h, k + 1, j) - p * y);
+                                               set(h, k, j, get(h, k, j) - p * x);
+                                       }
+                                       int j = (k + 3) < n ? k + 3 : n;
+
+                                       // column modification
+                                       for (int i = l; i <= j; ++i) {
+                                               p = x * get(h, i, k) + y * get(h, i, k + 1);
+                                               if (notlast) {
+                                                       p = p + z * get(h, i, k + 2);
+                                                       set(h, i, k + 2, get(h, i, k + 2) - p * r);
+                                               }
+                                               set(h, i, k + 1, get(h, i, k + 1) - p * q);
+                                               set(h, i, k, get(h, i, k) - p);
+                                       }
+
+                               } // k = m..na
+
+                               // cont3
+
+                       } // goto nextit            
+               }
+       }
+
+       // Given the unsymmetric matrix A, stored in the array
+       // a[0:n-1,0:n-1], this procedure reduces the sub-matrix of order
+       // l-k+1, which starts at the element a[k-1][k-1], and finishes at
+       // the element a[l-1][l-1], to Hessenberg form H, by
+       // non-orthogonal elementary transformations.  The matrix H is
+       // overwritten on A with details of the transformations stored in
+       // the remaining triangle under H and in the array iint[k-1:l-1].
+       //
+       // Additional parameters:
+       //
+       //   iint - gets row and column interchanges involved in reduction
+       //
+       protected static void elmhes(
+               double[][] a,
+               int[] iint,
+               int n,
+               int k,
+               int l) {
+
+               int la = l - 1;
+
+               for (int m = k + 1; m <= la; ++m) {
+                       int i = m;
+                       double x = 0;
+                       for (int j = m; j <= l; ++j) {
+                               if (abs(get(a, j, m - 1)) > abs(x)) {
+                                       x = get(a, j, m - 1);
+                                       i = j;
+                               }
+                       }
+                       set(iint, m, i - 1);
+                       if (i != m) { // interchange rows and columns of A
+                               for (int j = m - 1; j <= n; ++j) {
+                                       swap(a, i, j, m, j);
+                               }
+                               for (int j = 1; j <= l; ++j) {
+                                       swap(a, j, i, j, m);
+                               }
+                       } // interchange
+                       if (x != 0) {
+                               for (i = m + 1; i <= l; ++i) {
+                                       double y = get(a, i, m - 1);
+                                       if (y != 0) {
+                                               set(a, i, m - 1, y / x);
+                                               y = get(a, i, m - 1);
+                                               for (int j = m; j <= n; ++j) {
+                                                       set(a, i, j, get(a, i, j) - y * get(a, m, j));
+                                               }
+                                               for (int j = 1; j <= l; ++j) {
+                                                       set(a, j, m, get(a, j, m) + y * get(a, j, i));
+                                               }
+                                       }
+                               } // i
+                       }
+               } // m
+       }
+
+       // reduce the norm of a[0:n-1][0:n-1] by exact diagonal similarity
+       // transformations stored in d[0:n-1].  Modified from original:
+       // check for scaled identity matrix (k==0) in L1, L2 phases.
+       //
+       // Additional parameters:
+       //
+       //   lohi - two integers such that a[i][j] is equal to zero if
+       //            (1) i > j and
+       //            (2) j=0,...,lo-2 or i=hi,...,n-1
+       //
+       protected static void balance(
+               double[][] a,
+               int[] lohi,
+               double[] d,
+               int n,
+               int b) {
+
+               int b2 = b * b, l = 1, k = n;
+
+               // search for rows isolating an eigenvalue and push them down
+               for (boolean found = true; found && (k > 0);) { // L1
+                       for (int j = k; j >= 1; --j) {
+                               double r = 0;
+                               for (int i = 1; i <= k; ++i) {
+                                       if (i != j) {
+                                               r += abs(get(a, j, i));
+                                       }
+                               }
+                               if (r == 0) {
+                                       exc(k, a, d, n, j, k, l);
+                                       k--;
+                               } // goto L1
+                               else {
+                                       found = false;
+                               }
+                       }
+               }
+
+               // search for columns isolating an eigenvalue and push them left
+               for (boolean found = true; found && (k > 0);) { // L2
+                       for (int j = l; j <= k; ++j) {
+                               double c = 0;
+                               for (int i = l; i <= k; ++i) {
+                                       if (i != j) {
+                                               c += abs(get(a, i, j));
+                                       }
+                               }
+                               if (c == 0) {
+                                       exc(l, a, d, n, j, k, l);
+                                       l++;
+                               } // goto L2
+                               else {
+                                       found = false;
+                               }
+                       }
+               }
+
+               // now balance the submatrix in rows l through k
+               lohi[0] = l;
+               lohi[1] = k;
+               for (int i = l; i <= k; ++i)
+                       set(d, i, 1);
+               while (true) { // iteration
+                       boolean noconv = false;
+                       for (int i = l; i <= k; ++i) {
+                               double c = 0, r = 0;
+                               for (int j = l; j <= k; ++j) {
+                                       if (j != i) {
+                                               c += abs(get(a, j, i));
+                                               r += abs(get(a, i, j));
+                                       }
+                               }
+                               double g = r / b, f = 1, s = c + r;
+                               while (c < g) { // L3
+                                       f *= b;
+                                       c *= b2;
+                               }
+                               g = r * b;
+                               while (c >= g) { // L4
+                                       f /= b;
+                                       c /= b2;
+                               }
+                               // now balance
+                               if ((c + r) / f < 0.95 * s) {
+                                       g = 1 / f;
+                                       set(d, i, get(d, i) * f);
+                                       noconv = true;
+                                       for (int j = l; j <= n; ++j)
+                                               set(a, i, j, get(a, i, j) * g);
+                                       for (int j = l; j <= k; ++j)
+                                               set(a, j, i, get(a, j, i) * f);
+                               }
+                       }
+                       if (!noconv)
+                               break;
+               }
+       }
+
+       // exchange routine used by BALANCE
+       private static void exc(
+               int m,
+               double[][] a,
+               double[] d,
+               int n,
+               int j,
+               int k,
+               int l) {
+               set(d, m, j);
+
+               if (j != m) {
+                       for (int i = 1; i <= k; ++i) {
+                               swap(a, i, j, i, m);
+                       }
+                       for (int i = l; i <= n; ++i) {
+                               swap(a, j, i, m, i);
+                       }
+               }
+       }
+
+       // get, set allow us to use indices 1..N, as in original code -------------
+
+       private static double get(double[][] a, int i, int j) {
+               return a[i - 1][j - 1];
+       }
+
+       private static void set(double[] a, int i, double v) {
+               a[i - 1] = v;
+       }
+
+       private static double get(double[] a, int i) {
+               return a[i - 1];
+       }
+
+       private static void set(double[][] a, int i, int j, double v) {
+               a[i - 1][j - 1] = v;
+       }
+
+       private static void set(int[] a, int i, int v) {
+               a[i - 1] = v;
+       }
+
+       // additional macros ------------------------------------------------------
+
+       private static double abs(double x) {
+               return Math.abs(x);
+       }
+
+       private static double sqrt(double x) {
+               return Math.sqrt(x);
+       }
+
+       private static void swap(double[][] a, int r, int c, int rr, int cc) {
+               double y = get(a, r, c);
+               set(a, r, c, get(a, rr, cc));
+               set(a, rr, cc, y);
+       }
+       
+       /**
+        * Returns an array of double-precision floating-point values
+        * contained in a Matrix.
+        * @param theMatrix
+        * @return 2D array of double
+        * @throws InvalidOperationException if theMatrix does not contain doubles
+        */
+       public static double[][] doubleValues(Matrix theMatrix)
+               throws InvalidOperationException {
+               check_double(theMatrix);
+               int m = theMatrix.getRows(), n = theMatrix.getCols();
+               double[][] result = new double[m][n];
+               for (int i = 1; i <= m; ++i) {
+                       for (int j = 1; j <= n; ++j) {
+                               result[i - 1][j - 1] = doubleValue(theMatrix, i, j);
+                       }
+               }
+               return result;
+       }
+       
+       /**
+        * Returns a 2xN array containing the real and imaginary components of
+        * a complex vector of length N.
+        * @param theVector containing the Complex values
+        * @return 2D array of double
+        * @throws InvalidOperationException if theVector does not contain Complex
+        */
+       public static double[][] complexValues(Vector theVector)
+               throws InvalidOperationException {
+
+               check_complex(theVector);
+
+               int n = theVector.length();
+
+               double[][] values = new double[2][n];
+
+               for (int i = 0; i < n; ++i) {
+                       FieldElement f = theVector.entries[i];
+                       Complex c = (Complex) f;
+                       values[0][i] = c.getReal().doubleValue();
+                       values[1][i] = c.getImaginary().doubleValue();
+               }
+
+               return values;
+       }
+       
+       /**
+        * Returns the double-precision floating-point value in a FieldElement.
+        * @param d the element
+        * @return double contained in d
+        * @throws InvalidOperationException if d does not contain a double
+        */
+       public static double doubleValue(FieldElement d)
+               throws InvalidOperationException {
+               check_double(d);
+               return unwrap(d);
+       }
+       
+       /**
+        * Returns the Ith double-precision floating-point value in a Vector.
+        * First index is 1.
+        * @param x the Vector
+        * @param i the index
+        * @return double contained in at v(i)
+        * @throws InvalidOperationException if v does not contain double
+        * @throws InvalidOperationException if the index is out of bounds
+        */
+       public static double doubleValue(Vector x, int i)
+               throws InvalidOperationException {
+               check_double(x);
+               return unwrap(x.getEntry(i));
+       }
+
+       /**
+        * Returns the I,Jth double-precision floating-point value in a Matrix.
+        * First index is 1,1.
+        * @param a the Matrix
+        * @param i row index
+        * @param j column index
+        * @return double contained in at a(i,j)
+        * @throws InvalidOperationException if v does not contain double
+        * @throws InvalidOperationException if either index is out of bounds
+        */
+       public static double doubleValue(Matrix a, int i, int j)
+               throws InvalidOperationException {
+               check_double(a);
+               return unwrap(a.get(i, j));
+       }
+       
+       
+       private static double unwrap(FieldElement f) {
+               return ((DoubleWrapper) f).value;
+       }
+
+       // Double, double, toil and trouble / If this don't work, your
+       // code is rubble
+
+       private static void check_double(Matrix a)
+               throws InvalidOperationException {
+               check_double(a.get(1, 1));
+       }
+
+
+       private static void check_double(FieldElement value)
+               throws InvalidOperationException {
+
+               check_type(value, new DoubleWrapper(0), "double");
+       }
+
+       private static void check_double(Vector v)
+               throws InvalidOperationException {
+               check_double(v.getEntry(1));
+       }
+       
+       private static void check_complex(Vector v)
+               throws InvalidOperationException {
+               check_complex(v.getEntry(1));
+       }
+       
+       private static void check_complex(FieldElement value)
+               throws InvalidOperationException {
+
+               check_type(value, new Complex(0, 0), "complex");
+       }
+       
+       private static void check_complex(Matrix a)
+               throws InvalidOperationException {
+               check_complex(a.get(1, 1));
+       }
+       
+       private static void check_type(
+               FieldElement value,
+               FieldElement check,
+               String name)
+               throws InvalidOperationException {
+
+               if (!value.getClass().equals(check.getClass())) {
+                       String err = "Matrix or Vector doesn't contain " + name;
+                       throw new InvalidOperationException(err);
+               }
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/InvalidOperationException.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/InvalidOperationException.java
new file mode 100644 (file)
index 0000000..5080b96
--- /dev/null
@@ -0,0 +1,15 @@
+package JLinAlg;
+
+import java.io.Serializable;
+
+/**
+ * This class provides a run-time exception that gets thrown whenever
+ * an invalid operation is attempted on a Vector or Matrix.
+ */
+
+public class InvalidOperationException extends RuntimeException implements Serializable{
+
+       public InvalidOperationException(String theMessage) {
+               super(theMessage);
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/LessThanComparator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/LessThanComparator.java
new file mode 100644 (file)
index 0000000..08b889b
--- /dev/null
@@ -0,0 +1,11 @@
+package JLinAlg;
+
+
+// class to return FieldElement.one() or FieldElement.zero(), depending on 
+// result of FieldElement less-than comparison
+class LessThanComparator extends FEComparator {
+
+       public boolean compare(FieldElement a, FieldElement b) {
+               return a.lt(b);
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/LessThanOrEqualToComparator.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/LessThanOrEqualToComparator.java
new file mode 100644 (file)
index 0000000..62b50a9
--- /dev/null
@@ -0,0 +1,11 @@
+package JLinAlg;
+
+
+// class to return FieldElement.one() or FieldElement.zero(), depending on 
+// result of FieldElement less than or equal to comparison
+class LessThanOrEqualToComparator extends FEComparator {
+
+       public boolean compare(FieldElement a, FieldElement b) {
+               return a.le(b);
+       }
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/LinAlgFactory.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/LinAlgFactory.java
new file mode 100644 (file)
index 0000000..6653e09
--- /dev/null
@@ -0,0 +1,255 @@
+package JLinAlg;
+
+import java.io.Serializable;
+import java.util.Random;
+
+/**
+ * This class provides a set of methods for generating various
+ * common types of matrices and vectors for an arbitrary 
+ * FieldElement type.
+ *
+ * @author Simon D. Levy, Andreas Keilhauer
+ */
+
+public class LinAlgFactory implements Serializable {
+
+       /**
+        * type of this LinAlgFactory
+        */
+       protected FieldElement type = null;
+
+       /**
+        * Creates a LinAlgFactory for a certain FieldElement type.
+        * @param type for this LinAlgFactory
+        */
+       public LinAlgFactory(FieldElement type) {
+               this.type = type;
+       }
+
+       /**
+        * Returns a Matrix of all ones.
+        * @param numberOfRows
+        * @param numberOfCols
+        * @return matrix of ones
+        */
+       public Matrix ones(int numberOfRows, int numberOfCols) {
+               return block_matrix(numberOfRows, numberOfCols, type.one());
+       }
+
+       /**
+        * Returns a Matrix of all zeros.
+        * @param numberOfRows
+        * @param numberOfCols
+        * @return matrix of zeros
+        */
+       public Matrix zeros(int numberOfRows, int numberOfCols) {
+               return block_matrix(numberOfRows, numberOfCols, type.zero());
+       }
+
+       /**
+        * Returns a Matrix of uniformly distributed random values.
+        * The kind of random values you get depends on the
+        * FieldElement you use to initialise the LinAlgFactory
+        * @param numberOfRows
+        * @param numberOfCols
+        * @param random random-number generator
+        * @return matrix of uniformly distributed random values
+        */
+       public Matrix uniformNoise(
+               int numberOfRows,
+               int numberOfCols,
+               Random random) {
+
+               Matrix a = new Matrix(numberOfRows, numberOfCols);
+               for (int i = 1; i <= numberOfRows; ++i) {
+                       for (int j = 1; j <= numberOfCols; ++j) {
+                               a.set(i, j, type.randomValue(random));
+                       }
+               }
+               return a;
+       }
+
+       /**
+        * Returns a Matrix of normally distributed random values.  Values are
+        * taken from a Gaussian distribution with zero mean and standard 
+        * deviation one.<BR>
+        * <STRONG>Note!</STRONG> Normal Distribution Issue<BR>
+        * For the following FieldElement types this method won't
+        * achieve values of the correct distribution: F2, FieldP
+        * @param numberOfRows
+        * @param numberOfCols
+        * @param random random-number generator
+        * @return Matrix of normally distributed random values
+        */
+       public Matrix gaussianNoise(
+               int numberOfRows,
+               int numberOfCols,
+               Random random) {
+
+               Matrix a = new Matrix(numberOfRows, numberOfCols);
+               for (int i = 1; i <= numberOfRows; ++i) {
+                       for (int j = 1; j <= numberOfCols; ++j) {
+                               a.set(i, j, type.gaussianRandomValue(random));
+                       }
+               }
+               return a;
+       }
+
+       /**
+        * Returns a Vector of all ones.
+        * @param length vector length
+        * @return vector of ones
+        */
+       public Vector ones(int length) {
+               return block_vector(length, type.one());
+       }
+
+       /**
+        * Returns a Vector of all zeros.
+        * @param length vector length
+        * @return vector of zeros
+        */
+       public Vector zeros(int length) {
+               return block_vector(length, type.zero());
+       }
+
+       /**
+        * Returns a Vector of uniformly distributed random values.
+        * @param length vector length
+        * @return vector of uniformly distributed random values
+        */
+       public Vector uniformNoise(int length, Random random) {
+               Vector v = new Vector(length);
+               for (int i = 1; i <= length; ++i) {
+                       v.set(i, randomValue(random));
+               }
+               return v;
+       }
+
+       /**
+        * Returns a Vector of uniformly distributed random values.<BR>
+        * <STRONG>Note!</STRONG> Normal Distribution Issue<BR>
+        * For the following FieldElement types this method won't 
+        * achieve values of correct distribution: F2, FieldP
+        * @param length vector length
+        * @return vector of uniformly distributed random values
+        */
+       public Vector gaussianNoise(int length, Random random) {
+               Vector v = new Vector(length);
+               for (int i = 1; i <= length; ++i) {
+                       v.set(i, gaussianRandomValue(random));
+               }
+               return v;
+       }
+
+       public FieldElement one() {
+               return type.one();
+       }
+
+       public FieldElement zero() {
+               return type.zero();
+       }
+
+       /**
+        * Returns a uniformly distributed random value. Refer to the
+        * documentation of the LinAlgFactory's type for further details.
+        * @param random 
+        * @return random value FieldElement
+        */
+       public FieldElement randomValue(Random random) {
+               return this.type.randomValue(random);
+       }
+
+       /**
+        * Returns a random value FieldElement with distribution N(0, 1)
+        * <BR><STRONG>Note!</STRONG> Normal Distribution Issue<BR>
+        * For the following FieldElement  types this method won't 
+        * achieve the correct distribution: F2, FieldP
+        * @param random
+        * @return random value FieldElement
+        */
+       public FieldElement gaussianRandomValue(Random random) {
+               return this.type.gaussianRandomValue(random);
+       }
+
+       /**
+        * Returns the identity Matrix. This is a square matrix with 
+        * ones on its diagonal and zeros elsewhere.
+        * @param size number of rows (= number of columns)
+        * @return identity matrix
+        */
+       public Matrix identity(int size) {
+               Matrix a = zeros(size, size);
+               for (int i = 1; i <= size; ++i) {
+                       a.set(i, i, type.one());
+               }
+               return a;
+       }
+
+       // return Vector full of value
+       private Vector block_vector(int length, FieldElement value) {
+               Vector v = new Vector(length);
+               for (int i = 1; i <= length; ++i) {
+                       v.set(i, value);
+               }
+               return v;
+       }
+
+       // return Matrix full of value
+       private Matrix block_matrix(
+               int numberOfRows,
+               int numberOfCols,
+               FieldElement value) {
+               Matrix a = new Matrix(numberOfRows, numberOfCols);
+               for (int i = 1; i <= numberOfRows; ++i) {
+                       for (int j = 1; j <= numberOfCols; ++j) {
+                               a.set(i, j, value);
+                       }
+               }
+               return a;
+       }
+
+       /**
+        * Returns a Matrix built from an array of double-precision floating-point
+        * values.
+        * @param theValues
+        * @return Matrix built from theValues
+        */
+       public Matrix buildMatrix(double[][] theValues)
+               throws InvalidOperationException {
+
+               return new Matrix(wrap(theValues));
+       }
+
+       /**
+        * Returns a Vector built from an array of double-precision floating-point
+        * values.
+        * @param theValues
+        * @return Vector built from theValues
+        */
+       public Vector buildVector(double[] theValues)
+               throws InvalidOperationException {
+               return new Vector(wrap(theValues));
+       }
+
+       // I am the Queen / Of the wrapping scene
+       public FieldElement[] wrap(double[] x) {
+               FieldElement[] d = new FieldElement[x.length];
+               for (int i = 0; i < x.length; ++i) {
+                       d[i] = type.instance(x[i]);
+               }
+               return d;
+       }
+
+       public FieldElement[][] wrap(double[][] x) {
+               int m = x.length, numberOfCols, n = x[0].length;
+               FieldElement[][] d = new FieldElement[m][n];
+               for (int i = 0; i < m; ++i) {
+                       for (int j = 0; j < n; ++j) {
+                               d[i][j] = type.instance(x[i][j]);
+                       }
+               }
+               return d;
+       }
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/LinSysSolver.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/LinSysSolver.java
new file mode 100644 (file)
index 0000000..19dc7ab
--- /dev/null
@@ -0,0 +1,261 @@
+package JLinAlg;
+
+import java.io.Serializable;
+import java.util.Stack;
+
+/**
+ * This class is capable of solving linear equations.
+ * 
+ * @author Andreas Keilhauer
+ */
+
+public class LinSysSolver implements Serializable {
+
+       /**
+        * Calculates the solution space of a given linear equation system of the
+        * form A*x=b.
+        * 
+        * @param a
+        *            coefficient matrix
+        * @param b
+        *            result vector
+        * @return solution space as an AffinLinearSubSpace.
+        */
+
+       public static AffineLinearSubspace solutionSpace(Matrix a, Vector b)
+                       throws InvalidOperationException {
+
+               if (a.getRows() != b.length()) {
+                       throw new InvalidOperationException(
+                                       "Tried to solve an equation system with a coefficient matrix"
+                                                       + " with " + a.getRows() + " rows and a"
+                                                       + " vector with length " + b.length()
+                                                       + ". Not correct format!");
+               }
+
+               Matrix extCoeff = LinSysSolver.isSolvableHelper(a, b);
+
+               if (extCoeff == null) {
+                       return null;
+               }
+
+               Stack swaps = new Stack();
+               for (int row = 1; row <= extCoeff.getRows(); row++) {
+                       if (extCoeff.get(row, row).isZero()) {
+                               int col = row;
+                               while (extCoeff.get(row, col).isZero()) {
+                                       col++;
+                               }
+                               swaps.push(new Integer(row));
+                               swaps.push(new Integer(col));
+                               extCoeff.swapCols(row, col);
+                       }
+               }
+
+               int dimension = a.getCols();
+
+               FieldElement zero = extCoeff.get(1, 1).zero();
+               FieldElement minusOne = zero.subtract(zero.one());
+
+               Vector[] generatingSystem = new Vector[extCoeff.getCols()
+                               - extCoeff.getRows() - 1];
+
+               for (int col = extCoeff.getRows() + 1; col <= extCoeff.getCols() - 1; col++) {
+                       Vector tmp = new Vector(dimension);
+                       for (int row = 1; row <= dimension; row++) {
+                               if (row <= extCoeff.getRows()) {
+                                       tmp.set(row, extCoeff.get(row, col));
+                               } else if (row == col) {
+                                       tmp.set(row, minusOne);
+                               } else {
+                                       tmp.set(row, zero);
+                               }
+                       }
+
+                       generatingSystem[col - (extCoeff.getRows() + 1)] = tmp;
+               }
+
+               Vector inhomogenousPart = new Vector(dimension);
+
+               for (int row = 1; row <= dimension; row++) {
+                       if (row <= extCoeff.getRows()) {
+                               inhomogenousPart
+                                               .set(row, extCoeff.get(row, extCoeff.getCols()));
+                       } else {
+                               inhomogenousPart.set(row, zero);
+                       }
+               }
+
+               while (!swaps.isEmpty()) {
+                       int index1 = ((Integer) swaps.pop()).intValue();
+                       int index2 = ((Integer) swaps.pop()).intValue();
+                       inhomogenousPart.swapEntries(index1, index2);
+                       for (int i = 0; i < generatingSystem.length; i++) {
+                               generatingSystem[i].swapEntries(index1, index2);
+                       }
+               }
+
+               if (inhomogenousPart.isZero()) {
+                       return new LinearSubspace(generatingSystem);
+               } else {
+                       return new AffineLinearSubspace(inhomogenousPart, generatingSystem,
+                                       true);
+               }
+
+       }
+
+       /**
+        * Calculates a solution of a given linear equation system of the form
+        * A*x=b.
+        * 
+        * @param a
+        *            coefficient matrix
+        * @param b
+        *            result vector
+        * @return solution as a Vector.
+        */
+
+       public static Vector solve(Matrix a, Vector b) {
+
+               if (a.getRows() != b.length()) {
+                       throw new InvalidOperationException(
+                                       "Tried to solve an equation system with a coefficient matrix"
+                                                       + " with " + a.getRows() + " rows and a"
+                                                       + " vector with length " + b.length()
+                                                       + ". Not correct format!");
+               }
+
+               Matrix extCoeff = LinSysSolver.isSolvableHelper(a, b);
+
+               if (extCoeff == null) {
+                       return null;
+               }
+
+               Stack swaps = new Stack();
+               for (int row = 1; row <= extCoeff.getRows(); row++) {
+                       if (extCoeff.get(row, row).isZero()) {
+                               int col = row;
+                               while (extCoeff.get(row, col).isZero()) {
+                                       col++;
+                               }
+                               swaps.push(new Integer(row));
+                               swaps.push(new Integer(col));
+                               extCoeff.swapCols(row, col);
+                       }
+               }
+
+               int dimension = a.getCols();
+
+               FieldElement zero = extCoeff.get(1, 1).zero();
+               Vector inhomogenousPart = new Vector(dimension);
+
+               for (int row = 1; row <= dimension; row++) {
+                       if (row <= extCoeff.getRows()) {
+                               inhomogenousPart
+                                               .set(row, extCoeff.get(row, extCoeff.getCols()));
+                       } else {
+                               inhomogenousPart.set(row, zero);
+                       }
+               }
+
+               while (!swaps.isEmpty()) {
+                       int index1 = ((Integer) swaps.pop()).intValue();
+                       int index2 = ((Integer) swaps.pop()).intValue();
+                       inhomogenousPart.swapEntries(index1, index2);
+               }
+
+               return inhomogenousPart;
+
+       }
+
+       /**
+        * Does something quite similar to isSolvable but is used by solve and
+        * solutionSpace
+        * 
+        * @param a
+        *            coefficient matrix
+        * @param b
+        *            result vector
+        * @return a.gaussjord() without zero rows or null if there is no solution
+        */
+
+       private static Matrix isSolvableHelper(Matrix a, Vector b) {
+               if (a.getRows() != b.length()) {
+                       throw new InvalidOperationException(
+                                       "Tried to solve an equation system with a coefficient matrix"
+                                                       + " with " + a.getRows() + " rows and a"
+                                                       + " vector with length " + b.length()
+                                                       + ". Not correct format!");
+               }
+
+               Matrix tmp = a.insertCol(a.getCols() + 1, b);
+               // The Following is equivalent to: return tmp.rank() == a.rank();
+               // But it is more efficient.
+
+               tmp = tmp.gaussjord();
+               int row = tmp.getRows();
+
+               // Find the index of the first not zero row.
+               while (row > 0 && tmp.isZeroRow(row)) {
+                       tmp = tmp.withoutRow(row);
+                       row--;
+               }
+
+               // Check whether there is any non zero entry in the first not zero row
+               // of tmp
+               // in a.gaussjord() (i.e. tmp without last column)
+               for (int col = 1; col < tmp.getCols(); col++) {
+                       if (!tmp.get(row, col).isZero()) {
+                               return tmp;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Tests whether a linear equation system (A*x=b) is solvable or not.
+        * 
+        * @param a
+        *            coefficient matrix
+        * @param b
+        *            result vector
+        * @return return true if and only if there is a solution for this linear
+        *         eqution system.
+        */
+
+       public static boolean isSolvable(Matrix a, Vector b) {
+
+               if (a.getRows() != b.length()) {
+                       throw new InvalidOperationException(
+                                       "Tried to solve an equation system with a coefficient matrix"
+                                                       + " with " + a.getRows() + " rows and a"
+                                                       + " vector with length " + b.length()
+                                                       + ". Not correct format!");
+               }
+
+               Matrix tmp = a.insertCol(a.getCols() + 1, b);
+               // The Following is equivalent to: return tmp.rank() == a.rank();
+               // But it is more efficient.
+
+               tmp = tmp.gausselim();
+               int row = tmp.getRows();
+
+               // Find the index of the first not zero row.
+               while (row > 0 && tmp.isZeroRow(row)) {
+                       row--;
+               }
+
+               // Check whether there is any non zero entry in the first not zero row
+               // of tmp
+               // in a.gaussjord() (i.e. tmp without last column)
+               for (int col = 1; col < tmp.getCols(); col++) {
+                       if (!tmp.get(row, col).isZero()) {
+                               return true;
+                       }
+               }
+
+               return false;
+
+       }
+
+}
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/LinearSubspace.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/LinearSubspace.java
new file mode 100644 (file)
index 0000000..4394ad0
--- /dev/null
@@ -0,0 +1,53 @@
+package JLinAlg;
+
+import java.io.Serializable;
+
+/**
+ * This class represents a linear subspace.
+ * 
+ * @author Andreas Keilhauer
+ */
+
+public class LinearSubspace extends AffineLinearSubspace implements
+               Serializable {
+
+       /**
+        * This constructs a linear subspace with the given generating System.
+        * 
+        * @param generatingSystem
+        */
+
+       public LinearSubspace(Vector[] generatingSystem) {
+               super(null, generatingSystem);
+       }
+       
+       /**
+        * This constructs a linear subspace with the given generating System.
+        * The normalized flag, which is usually set after
+        * normalize is executed is also set.
+        * 
+        * @param generatingSystem
+        * @param normalized
+        */
+       
+       public LinearSubspace(Vector[] generatingSystem, boolean normalized) {
+               super(null, generatingSystem, normalized);
+       }
+
+       /**
+        * Returns a String representation of this linear subspace.
+        * 
+        * @return String representation
+        */
+       public String toString() {
+               String tmp = "< { ";
+               for (int i = 0; i < this.generatingSystem.length - 1; i++) {
+                       tmp += this.generatingSystem[i].toString() + ", ";
+               }
+               if (this.generatingSystem.length > 0) {
+                       tmp += this.generatingSystem[this.generatingSystem.length - 1];
+               }
+               return tmp + " } >";
+
+       }
+}
\ No newline at end of file
diff --git a/Splitter-ng-plugin-JSharing/src/JLinAlg/Matrix.java b/Splitter-ng-plugin-JSharing/src/JLinAlg/Matrix.java
new file mode 100644 (file)
index 0000000..53070e0
--- /dev/null
@@ -0,0 +1,1741 @@
+package JLinAlg;
+
+import java.io.Serializable;
+
+/**
+ * This class represents a matrix.
+ * 
+ * @author Andreas Keilhauer, Simon D. Levy
+ */
+
+public class Matrix implements Serializable {
+
+       protected int numOfRows;
+
+       protected int numOfCols;
+
+       protected FieldElement[][] entries;
+
+       /**
+        * Constructs an empty Matrix with a certain number of rows and columns.
+        * 
+        * @param numberOfRows
+        * @param numberOfCols
+        */
+
+       public Matrix(int numberOfRows, int numberOfCols) {
+               this.numOfRows = numberOfRows;
+               this.numOfCols = numberOfCols;
+               this.entries = new FieldElement[numberOfRows][numberOfCols];
+
+       }
+
+       /**
+        * Constructs a Matrix with a certain number of rows and columns and and
+        * fills it with FieldElements from one FieldElement array.
+        * 
+        * @param numberOfRows
+        * @param theEntries
+        *            in a FieldElement array.
+        * @throws InvalidOperationException
+        *             if theEntries is null
+        * @throws InvalidOperationException
+        *             if numberOfRows is not valid
+        */
+
+       public Matrix(FieldElement[] theEntries, int numberOfRows)
+                       throws InvalidOperationException {
+               if (theEntries == null) {
+                       throw new InvalidOperationException(
+                                       "Tried to construct matrix with a null entry array");
+               }
+               if (theEntries.length % numberOfRows != 0) {
+                       throw new InvalidOperationException(
+                                       "Tried to construct matrix with " + theEntries.length
+                                                       + " entries and " + numberOfRows + " rows");
+
+               }
+               this.numOfRows = numberOfRows;
+               this.numOfCols = theEntries.length / numberOfRows;
+               this.entries = new FieldElement[this.numOfRows][this.numOfCols];
+               for (int i = 0; i < this.numOfRows; i++) {
+                       for (int j = 0; j < this.numOfCols; j++) {
+                               entries[i][j] = theEntries[i * this.numOfCols + j];
+                       }
+               }
+       }
+
+       /**
+        * Constructs a Matrix out of an array of row vectors.
+        * 
+        * @param rowVectors
+        *            as an array of Vectors
+        * @throws InvalidOperationException
+        *             if rowVectors is null
+        * @throws InvalidOperationException
+        *             if rowVectors contains a null Vector
+        * @throws InvalidOperationException
+        *             if rowVectors contains Vectors of unequal lengths
+        */
+
+       public Matrix(Vector[] rowVectors) throws InvalidOperationException {
+               if (rowVectors == null) {
+                       throw new InvalidOperationException(
+                                       "Tried to construct matrix but array of row vectors was null");
+               }
+               for (int i = 0; i < rowVectors.length; i++) {
+                       if (rowVectors[i] == null) {
+                               throw new InvalidOperationException(
+                                               "Tried to construct matrix and found null-vector");
+                       }
+               }
+               int vectorLength = rowVectors[0].length();
+               for (int i = 0; i < rowVectors.length; i++) {
+                       if (rowVectors[i].length() != vectorLength) {
+                               throw new InvalidOperationException(
+                                               "Tried to construct matrix but not all vectors"
+                                                               + " had the same length");
+                       }
+               }
+
+               numOfRows = rowVectors.length;
+               numOfCols = vectorLength;
+               entries = new FieldElement[numOfRows][numOfCols];
+
+               for (int k = 0; k < numOfRows; k++) {
+                       for (int l = 0; l < numOfCols; l++) {
+                               entries[k][l] = rowVectors[k].getEntry(l + 1);
+                       }
+               }
+       }
+
+       /**
+        * Constructs a Matrix out of a two dimensional array of FieldElements.
+        * 
+        * @param theEntries
+        *            as a two dimensional FieldElement array.
+        * @throws InvalidOperationException
+        *             if theEntries is null
+        */
+
+       public Matrix(FieldElement[][] theEntries) throws InvalidOperationException {
+               if (theEntries == null) {
+                       throw new InvalidOperationException(
+                                       "Tried to construct matrix but entry array was null");
+               }
+               this.numOfRows = theEntries.length;
+               this.numOfCols = theEntries[0].length;
+
+               this.entries = theEntries;
+       }
+
+       /**
+        * Constructs a Matrix out of a two dimensional array of FieldElements. But
+        * with the dimensions given it is faster than the constructor above because
+        * it doesnt check any integrity of the entries-array.
+        * 
+        * @param theEntries
+        * @param rows
+        * @param cols
+        */
+
+       public Matrix(FieldElement[][] theEntries, int rows, int cols) {
+               this.numOfRows = rows;
+               this.numOfCols = cols;
+               this.entries = theEntries;
+       }
+
+       /**
+        * Gets the number of rows of this Matrix.
+        * 
+        * @return number of rows
+        */
+
+       public int getRows() {
+               return numOfRows;
+       }
+
+       /**
+        * Gets the number of columns of this Matrix.
+        * 
+        * @return number of columns
+        */
+
+       public int getCols() {
+               return numOfCols;
+       }
+
+       public FieldElement[][] getEntries() {
+               return this.entries;
+       }
+
+       /**
+        * Gets the entry of this Matrix at a certain row - and col index.
+        * 
+        * @param rowIndex
+        * @param colIndex
+        * @return the FieldElement at this row - and column index
+        * @throws InvalidOperationException
+        *             if rowIndex is not between 1 and numberOfRows or colIndex is
+        *             not between 1 and numberOfCols
+        */
+
+       public FieldElement get(int rowIndex, int colIndex)
+                       throws InvalidOperationException {
+               FieldElement returnValue = null;
+               try {
+                       returnValue = entries[rowIndex - 1][colIndex - 1];
+               } catch (ArrayIndexOutOfBoundsException e) {
+                       if (rowIndex > this.numOfRows || rowIndex < 1) {
+                               throw new InvalidOperationException("Tried row index "
+                                               + rowIndex + ". Only row indices from 1 to "
+                                               + this.numOfRows + " valid");
+                       } else {
+                               throw new InvalidOperationException("Tried column index "
+                                               + colIndex + ". Only column indices " + "from 1 to "
+                                               + this.numOfCols + " valid");
+                       }
+               }
+               return returnValue;
+       }
+
+       /**
+        * Sets the entry of this Matrix at a certain row - and col index.
+        * 
+        * @param rowIndex
+        * @param colIndex
+        * @param newEntry
+        * @throws InvalidOperationException
+        *             if rowIndex or colIndex is invalid
+        */
+
+       public void set(int rowIndex, int colIndex, FieldElement newEntry)
+                       throws InvalidOperationException {
+               try {
+                       entries[rowIndex - 1][colIndex - 1] = newEntry;
+               } catch (ArrayIndexOutOfBoundsException e) {
+                       if (rowIndex > this.numOfRows || rowIndex < 1) {
+                               throw new InvalidOperationException("Tried row index "
+                                               + rowIndex + ". Only row indices from 1 to "
+                                               + this.numOfRows + " valid");
+                       } else {
+                               throw new InvalidOperationException("Tried column index "
+                                               + colIndex + ". Only column indices " + "from 1 to "
+                                               + this.numOfCols + " valid");
+                       }
+               }
+       }
+
+       /**
+        * Gets the row vector at a certain row index.
+        * 
+        * @param rowIndex
+        */
+       public Vector getRow(int rowIndex) {
+               FieldElement[] rowEntries = new FieldElement[numOfCols];
+               for (int i = 0; i < numOfCols; i++) {
+                       try {
+                               rowEntries[i] = entries[rowIndex - 1][i];
+                       } catch (ArrayIndexOutOfBoundsException a) {
+                               throw new InvalidOperationException("Tried row index "
+                                               + rowIndex + ". Only row indices from 1 to "
+                                               + this.numOfRows + " valid");
+                       }
+               }
+               return new Vector(rowEntries);
+       }
+
+       /**
+        * Gets the column vector at a certain column index.
+        * 
+        * @param colIndex
+        */
+
+       public Vector getCol(int colIndex) {
+               FieldElement[] colEntries = new FieldElement[numOfRows];
+               for (int i = 0; i < numOfRows; i++) {
+                       try {
+                               colEntries[i] = entries[i][colIndex - 1];
+                       } catch (ArrayIndexOutOfBoundsException a) {
+                               throw new InvalidOperationException("Tried row index "
+                                               + colIndex + ". Only row indices from 1 to "
+                                               + this.numOfCols + " valid");
+                       }
+
+               }
+               return new Vector(colEntries);
+       }
+
+       /**
+        * Sets the row vector at a certain index of the matrix.
+        * 
+        * @param rowIndex
+        * @param vector
+        * @throws InvalidOperationException
+        *             if index out of bounds
+        */
+
+       public void setRow(int rowIndex, Vector vector)
+                       throws InvalidOperationException {
+
+               if (this.numOfCols != vector.length()) {
+                       throw new InvalidOperationException("Tried to set row number "
+                                       + rowIndex + "of a matrix with " + this.numOfCols
+                                       + " columns with a vector having length " + vector.length()
+                                       + " ");
+               }
+
+               for (int i = 1; i <= vector.length(); i++) {
+                       set(rowIndex, i, vector.getEntry(i));
+               }
+       }
+
+       /**
+        * Sets the column vector at a certain column index of the matrix.
+        * 
+        * @param colIndex
+        * @param vector
+        */
+
+       public void setCol(int colIndex, Vector vector) {
+
+               if (this.numOfRows != vector.length()) {
+                       throw new InvalidOperationException("Tried to set column number "
+                                       + colIndex + "of a matrix with " + this.numOfRows
+                                       + " rows with a vector having length " + vector.length()
+                                       + " ");
+               }
+
+               for (int i = 1; i <= vector.length(); i++) {
+                       set(i, colIndex, vector.getEntry(i));
+               }
+       }
+
+       /**
+        * Returns this Matrix without the row at a certain row index.
+        * 
+        * @param rowIndex
+        * @return the matrix without the row at the row index.
+        */
+
+       public Matrix withoutRow(int rowIndex) {
+               // Exception still missing here
+               Matrix tmp = new Matrix(this.getRows() - 1, this.getCols());
+               int counter = 0;
+               for (int i = 1; i <= this.getRows(); i++) {
+                       counter++;
+                       if (i == rowIndex) {
+                               counter--;
+                               continue;
+                       }
+                       tmp.setRow(counter, this.getRow(i));
+               }
+               return tmp;
+       }
+
+       /**
+        * Returns this Matrix without the column at a certain column index.
+        * 
+        * @param colIndex
+        * @return the matrix without the column at the column index.
+        */
+
+       public Matrix withoutCol(int colIndex) {
+               // Exception still missing here
+               Matrix tmp = new Matrix(this.getRows(), this.getCols() - 1);
+               int counter = 0;
+               for (int i = 1; i <= this.getCols(); i++) {
+                       counter++;
+                       if (i == colIndex) {
+                               counter--;
+                               continue;
+                       }
+                       tmp.setCol(counter, this.getCol(i));
+               }
+               return tmp;
+       }
+
+       /**
+        * Returns a Matrix with a Vector inserted at specified index as a column.
+        * Index 1 will it put at the beginning and index numOfCols+1 will attach it
+        * to the end.
+        * 
+        * @param vector
+        * @param colIndex
+        * @return matrix with vector inserted.
+        * @throws InvalidOperationException
+        *             if index out of bounds
+        */
+
+       public Matrix insertCol(int colIndex, Vector vector)
+                       throws InvalidOperationException {
+
+               if (this.getRows() != vector.length()) {
+                       throw new InvalidOperationException("This vector\n" + vector
+                                       + "\n cannot be attached to " + "the Matrix\n" + this
+                                       + " as a column vector. The length does " + "not match");
+               }
+
+               if (colIndex < 1 || colIndex > this.getCols() + 1) {
+                       throw new InvalidOperationException(colIndex
+                                       + " is not a valid column index for inserting " + vector
+                                       + " into\n" + this);
+               }
+
+               Matrix tmp = new Matrix(this.getRows(), this.getCols() + 1);
+               int colOffset = 0;
+               for (int col = 1; col <= tmp.getCols(); col++) {
+                       if (col == colIndex) {
+                               tmp.setCol(col, vector);
+                               colOffset = 1;
+                       } else {
+                               tmp.setCol(col, this.getCol(col - colOffset));
+                       }
+               }
+
+               return tmp;
+       }
+
+       /**
+        * Returns a Matrix with a Vector inserted at specified index as a row.
+  &n