* green/Fraction/Makefile.am : Remove Makefile.
* green/Fraction/main.cc : Remove source.
* green/Fraction/frac.hh : Remove source.
* green/Fraction/frac.cc : Remove source.
* green/Fraction : Remove directory.
* green/fraction : New directory.
* green/fraction/Makefile.am : New Makefile.
* green/fraction/sign_prod.hh : New source.
* green/fraction/gcd.hh : New source.
* green/fraction/frac.hh : New source.
* green/fraction/frac.cc : New source.
---
trunk/milena/sandbox/green/Fraction/frac.cc | 271 ---------
trunk/milena/sandbox/green/Fraction/main.cc | 112 ----
.../green/{Fraction => fraction}/Makefile.am | 0
trunk/milena/sandbox/green/fraction/frac.cc | 423 +++++++++++++
.../sandbox/green/{Fraction => fraction}/frac.hh | 641 ++++++++++----------
trunk/milena/sandbox/green/fraction/gcd.hh | 91 +++
trunk/milena/sandbox/green/fraction/sign_prod.hh | 74 +++
7 files changed, 919 insertions(+), 693 deletions(-)
delete mode 100644 trunk/milena/sandbox/green/Fraction/frac.cc
delete mode 100644 trunk/milena/sandbox/green/Fraction/main.cc
rename trunk/milena/sandbox/green/{Fraction => fraction}/Makefile.am (100%)
create mode 100644 trunk/milena/sandbox/green/fraction/frac.cc
rename trunk/milena/sandbox/green/{Fraction => fraction}/frac.hh (50%)
create mode 100644 trunk/milena/sandbox/green/fraction/gcd.hh
create mode 100644 trunk/milena/sandbox/green/fraction/sign_prod.hh
diff --git a/trunk/milena/sandbox/green/Fraction/frac.cc
b/trunk/milena/sandbox/green/Fraction/frac.cc
deleted file mode 100644
index 4a7f452..0000000
--- a/trunk/milena/sandbox/green/Fraction/frac.cc
+++ /dev/null
@@ -1,271 +0,0 @@
-#include <iostream>
-#include "frac.hh"
-
-//
-// TEST INSTANTIATION
-//
-void test_instantiation_without_argument()
-{
- const mln::algebra::frac<int> constant;
- mln::algebra::frac<int> variable;
-
- mln_assertion(constant == variable);
- std::cout << "const frac<T> f : ok" << std::endl;
- std::cout << "frac<T> f : ok" << std::endl;
-}
-
-void test_instantiation_numerator_denominator()
-{
- const mln::algebra::frac<int> constant(2,5);
- mln::algebra::frac<int> variable(2,5);
-
- mln_assertion(constant == variable);
- std::cout << "const frac<T> f(n,d) : ok" << std::endl;
- std::cout << "frac<T> f(n,d) : ok" << std::endl;
-}
-
-void test_instantiation_frac()
-{
- const mln::algebra::frac<int> ref_int(2,5);
- const mln::algebra::frac<long> ref_long(2,5);
-
- const mln::algebra::frac<int> constant1 = ref_int;
- const mln::algebra::frac<int> constant2 = ref_long;
- mln::algebra::frac<int> variable1 = ref_int;
- mln::algebra::frac<int> variable2 = ref_long;
-
- mln_assertion(constant1 == ref_int);
- mln_assertion(constant2 == ref_long);
- mln_assertion(variable1 == ref_int);
- mln_assertion(variable2 == ref_long);
- std::cout << "const frac<T> f = frac<T> : ok" <<
std::endl;
- std::cout << "const frac<T> f = frac<F> : ok" <<
std::endl;
- std::cout << "frac<T> f = frac<T> : ok" <<
std::endl;
- std::cout << "frac<T> f = frac<F> : ok" <<
std::endl;
-}
-
-void test_instantiation_zero()
-{
- const mln::algebra::frac<int> zero(0,0);
- const mln::algebra::frac<int> f_cst = mln::literal::zero;
- mln::algebra::frac<int> f_var = mln::literal::zero;
-
- mln_assertion(zero == f_cst);
- mln_assertion(zero == f_var);
- std::cout << "const frac<T> f = zero : ok" << std::endl;
- std::cout << "frac<T> f = zero : ok" << std::endl;
-}
-
-void test_instantiation_one()
-{
- const mln::algebra::frac<int> one(1,0);
- const mln::algebra::frac<int> f_cst = mln::literal::one;
- mln::algebra::frac<int> f_var = mln::literal::one;
-
- mln_assertion(one == f_cst);
- mln_assertion(one == f_var);
- std::cout << "const frac<T> f = one : ok" << std::endl;
- std::cout << "frac<T> f = one : ok" << std::endl;
-}
-
-void test_instantiation_integer()
-{
- const mln::algebra::frac<int> ref(5,0);
- const mln::algebra::frac<int> f_cst = 5;
- mln::algebra::frac<int> f_var = 5;
-
- mln_assertion(ref == f_cst);
- mln_assertion(ref == f_var);
- std::cout << "const frac<T> f = integer : ok" <<
std::endl;
- std::cout << "frac<T> f = integer : ok" <<
std::endl;
-}
-
-
-//
-// TEST ASSIGNEMENT
-//
-void test_assignement_zero()
-{
- const mln::algebra::frac<int> zero(0,0);
- mln::algebra::frac<int> f;
-
- f = mln::literal::zero;
- mln_assertion(zero == f);
- std::cout << "frac = zero : ok" << std::endl;
-}
-
-void test_assignement_one()
-{
- const mln::algebra::frac<int> one(1,0);
- mln::algebra::frac<int> f;
-
- f = mln::literal::one;
- mln_assertion(one == f);
- std::cout << "frac = one : ok" << std::endl;
-}
-
-void test_assignement_frac()
-{
- const mln::algebra::frac<int> ref(2,3);
- mln::algebra::frac<int> f;
-
- f = ref;
- mln_assertion(ref == f);
- std::cout << "frac = frac : ok" << std::endl;
-}
-
-void test_assignement_integer()
-{
- const mln::algebra::frac<int> ref(5,0);
- mln::algebra::frac<int> f;
-
- f = 5;
- mln_assertion(ref == f);
- std::cout << "frac = integer: ok" << std::endl;
-}
-
-int main()
-{
- using namespace std;
- using namespace mln;
- using namespace mln::algebra;
-
- trace::quiet = true;
-
- // Testing instanciation
- frac<int> f0;
- frac<int> op1a(5,10);
- frac<int> op1b(op1a);
- frac<int> op2a(1,2);
- frac<int> op2b = op2a;
- int op3a = 1;
- int op3b = 1;
- int op4a = 2;
- int op4b = 2;
- frac<int> resPlus(literal::one);
- frac<int> resMinus(literal::zero);
- frac<int> resTimes(1,4);
- frac<int> resDiv(literal::one);
- frac<int> resPlusScalar(3,2);
- frac<int> resMinusScalar(-1,2);
- frac<int> resTimesScalar(literal::one);
- frac<int> resDivScalar(1,4);
- frac<int> resUminus(-1,4);
- frac<int> resZero(0,0);
- frac<int> resOne(1,0);
- cout << "frac<T> f : ok" << endl;
-
- test_instantiation_without_argument();
- test_instantiation_numerator_denominator();
- test_instantiation_frac();
- test_instantiation_zero();
- test_instantiation_one();
- test_instantiation_integer();
-
- // trace::quiet = false;
-
- //trace::quiet = true;
-
- test_assignement_zero();
- test_assignement_one();
- test_assignement_frac();
- test_assignement_integer();
-
-
- // Test frac.eval()
- mln_assertion(0.5 == op2b.eval());
- mln_assertion(op2a == op2b);
- cout << "frac.eval() : ok" << endl;
-
- // Test - frac
- mln_assertion(resUminus == (-op2b));
- cout << "- frac() : ok" << endl;
-
- // Test frac + frac
- mln_assertion(resPlus == (op1b + op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac + frac : ok" << endl;
-
- // Test frac - frac
- mln_assertion(resMinus == (op1b - op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac - frac : ok" << endl;
-
- // Test frac * frac
- mln_assertion(resTimes == (op1b * op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac * frac : ok" << endl;
-
- // Test frac / frac
- mln_assertion(resDiv == (op1b / op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac / frac : ok" << endl;
-
- // Test frac + scalar
- mln_assertion(resPlusScalar == (op1b + op3b));
- mln_assertion(op1a == op1b);
- mln_assertion(op3a == op3b);
- cout << "frac + scalar : ok" << endl;
-
- // Test frac - scalar
- mln_assertion(resMinusScalar == (op1b - op3b));
- mln_assertion(op1a == op1b);
- mln_assertion(op3a == op3b);
- cout << "frac - scalar : ok" << endl;
-
- // Test frac * scalar
- mln_assertion(resTimesScalar == (op1b * op4b));
- mln_assertion(op1a == op1b);
- mln_assertion(op4a == op4b);
- cout << "frac * scalar : ok" << endl;
-
- // Test frac / scalar
- mln_assertion(resDivScalar == (op1b / op4b));
- mln_assertion(op1a == op1b);
- mln_assertion(op4a == op4b);
- cout << "frac / scalar : ok" << endl;
-
- return 0;
-}
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/data/compute.hh>
-#include <mln/accu/math/sum.hh>
-#include <mln/accu/stat/mean.hh>
-#include <mln/accu/stat/variance.hh>
-
-
-int main2()
-{
- using namespace mln;
- using namespace std;
- using namespace mln::algebra;
-
- image2d<value::int_u8> input;
- io::pgm::load(input, "/usr/local/share/olena/images/small.pgm");
-
- /*
- accu::math::sum< value::int_u8 > sum0;
- accu::math::sum< value::int_u8, frac<long> > sum1;
-
- cout << data::compute(sum0, input) << endl;
- cout << data::compute(sum1, input) << endl;
-
- accu::stat::mean< value::int_u8 > mean0;
- accu::stat::mean< value::int_u8, frac<long> > mean1;
- */
- // cout << data::compute(mean0, input) << endl;
- //cout << data::compute(mean1, input) << endl;
-
- //frac<long> count = data::compute(accu::math::count< frac<long> >(),
input);
- //frac<long> variance = data::compute(accu::stat::variance< frac<long>,
frac<long>, frac<long> >(), input);
-
-
- return 0;
-}
diff --git a/trunk/milena/sandbox/green/Fraction/main.cc
b/trunk/milena/sandbox/green/Fraction/main.cc
deleted file mode 100644
index 0f6373c..0000000
--- a/trunk/milena/sandbox/green/Fraction/main.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <iostream>
-#include "frac.hh"
-
-#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/accu/stat/variance.hh>
-#include <mln/data/compute.hh>
-
-int main2()
-{
- using namespace std;
- using namespace mln;
- using namespace mln::algebra;
-
- trace::quiet = true;
-
- // Testing instanciation
- frac<int> f0;
- frac<int> op1a(5,10);
- frac<int> op1b(op1a);
- frac<int> op2a(1,2);
- frac<int> op2b = op2a;
- int op3a = 1;
- int op3b = 1;
- int op4a = 2;
- int op4b = 2;
- frac<int> resPlus(literal::one);
- frac<int> resMinus(literal::zero);
- frac<int> resTimes(1,4);
- frac<int> resDiv(literal::one);
- frac<int> resPlusScalar(3,2);
- frac<int> resMinusScalar(-1,2);
- frac<int> resTimesScalar(literal::one);
- frac<int> resDivScalar(1,4);
- frac<int> resUminus(-1,4);
-
- // Test frac.eval()
- mln_assertion(0.5 == op2b.eval());
- mln_assertion(op2a == op2b);
- cout << "frac.eval() : ok" << endl;
-
- // Test - frac
- mln_assertion(resUminus == (-op2b));
- cout << "- frac() : ok" << endl;
-
- // Test frac + frac
- mln_assertion(resPlus == (op1b + op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac + frac : ok" << endl;
-
- // Test frac - frac
- mln_assertion(resMinus == (op1b - op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac - frac : ok" << endl;
-
- // Test frac * frac
- mln_assertion(resTimes == (op1b * op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac * frac : ok" << endl;
-
- // Test frac / frac
- mln_assertion(resDiv == (op1b / op2b));
- mln_assertion(op1a == op1b);
- mln_assertion(op2a == op2b);
- cout << "frac / frac : ok" << endl;
-
- // Test frac + scalar
- mln_assertion(resPlusScalar == (op1b + op3b));
- mln_assertion(op1a == op1b);
- mln_assertion(op3a == op3b);
- cout << "frac + scalar : ok" << endl;
-
- // Test frac - scalar
- mln_assertion(resMinusScalar == (op1b - op3b));
- mln_assertion(op1a == op1b);
- mln_assertion(op3a == op3b);
- cout << "frac - scalar : ok" << endl;
-
- // Test frac * scalar
- mln_assertion(resTimesScalar == (op1b * op4b));
- mln_assertion(op1a == op1b);
- mln_assertion(op4a == op4b);
- cout << "frac * scalar : ok" << endl;
-
- // Test frac / scalar
- mln_assertion(resDivScalar == (op1b / op4b));
- mln_assertion(op1a == op1b);
- mln_assertion(op4a == op4b);
- cout << "frac / scalar : ok" << endl;
-
- return 0;
-}
-
-int main()
-{
- using namespace mln;
- using namespace std;
- using namespace mln::algebra;
-
- image2d<value::int_u8> input;
- io::pgm::load(input, "/usr/local/share/olena/images/small.pgm");
-
-
- frac<long> variance = data::compute(accu::stat::variance< frac<long>,
frac<long>, frac<long> >(), input);
-
-
- return 0;
-}
diff --git a/trunk/milena/sandbox/green/Fraction/Makefile.am
b/trunk/milena/sandbox/green/fraction/Makefile.am
similarity index 100%
rename from trunk/milena/sandbox/green/Fraction/Makefile.am
rename to trunk/milena/sandbox/green/fraction/Makefile.am
diff --git a/trunk/milena/sandbox/green/fraction/frac.cc
b/trunk/milena/sandbox/green/fraction/frac.cc
new file mode 100644
index 0000000..b8e8520
--- /dev/null
+++ b/trunk/milena/sandbox/green/fraction/frac.cc
@@ -0,0 +1,423 @@
+#include <iostream>
+#include "frac.hh"
+
+//
+// TEST INSTANTIATION
+//
+void test_instantiation_without_argument()
+{
+ const mln::algebra::frac<int> frac;
+
+ std::cout << "frac<T> frac : ok" << std::endl;
+}
+
+void test_instantiation_numerator_denominator()
+{
+ const mln::algebra::frac<int> frac(-2,5);
+
+ std::cout << "frac<T> frac(n,d) : ok" << std::endl;
+}
+
+void test_instantiation_frac()
+{
+ const mln::algebra::frac<int> ref(-2,5);
+ const mln::algebra::frac<int> frac = ref;
+
+ mln_assertion(ref == frac);
+
+ std::cout << "frac<T> frac = frac : ok" << std::endl;
+}
+
+void test_instantiation_zero()
+{
+ const mln::algebra::frac<int> ref(0,1);
+ const mln::algebra::frac<int> frac = mln::literal::zero;
+
+ mln_assertion(ref == frac);
+ std::cout << "frac<T> frac = zero : ok" << std::endl;
+}
+
+void test_instantiation_one()
+{
+ const mln::algebra::frac<int> ref(1,1);
+ const mln::algebra::frac<int> frac = mln::literal::one;
+
+ mln_assertion(ref == frac);
+ std::cout << "frac<T> frac = one : ok" << std::endl;
+}
+
+void test_instantiation_integer()
+{
+ const mln::algebra::frac<int> ref(5,1);
+ const mln::algebra::frac<int> frac = 5;
+
+ mln_assertion(ref == frac);
+ std::cout << "frac<T> frac = integer : ok" << std::endl;
+}
+
+
+//
+// TEST FRAC_BASE_
+//
+void test_frac_base_accessor()
+{
+ const int ref1 = 1;
+ const int ref2 = 2;
+ const mln::math::sign_t ref3 = mln::math::negative;
+ const float ref4 = -0.5;
+ const mln::algebra::frac<int> frac(-1, 2);
+
+ mln_assertion(ref1 == frac.numerator());
+ mln_assertion(ref2 == frac.denominator());
+ mln_assertion(ref3 == frac.sign());
+ mln_assertion(ref4 == frac.eval());
+
+ std::cout << "frac.numerator() : ok" << std::endl;
+ std::cout << "frac.denominator() : ok" << std::endl;
+ std::cout << "frac.sign() : ok" << std::endl;
+ std::cout << "frac.eval() : ok" << std::endl;
+}
+
+void test_frac_base_manipulator()
+{
+ const int ref1 = 5;
+ const int ref2 = 3;
+ const mln::algebra::frac<int> frac(-25,15);
+
+ mln_assertion(ref1 == frac.numerator());
+ mln_assertion(ref2 == frac.denominator());
+ std::cout << "frac.indicible() : ok" << std::endl;
+}
+
+
+//
+// TEST ASSIGNEMENT
+//
+void test_assignement_zero()
+{
+ const mln::algebra::frac<int> ref(0,1);
+ mln::algebra::frac<int> frac;
+
+ frac = mln::literal::zero;
+ mln_assertion(ref == frac);
+
+ std::cout << "frac = zero : ok" << std::endl;
+}
+
+void test_assignement_one()
+{
+ const mln::algebra::frac<int> ref(1,1);
+ mln::algebra::frac<int> frac;
+
+ frac = mln::literal::one;
+ mln_assertion(ref == frac);
+
+ std::cout << "frac = one : ok" << std::endl;
+}
+
+void test_assignement_frac()
+{
+ const mln::algebra::frac<int> ref(-2,3);
+ mln::algebra::frac<int> frac;
+
+ frac = ref;
+ mln_assertion(ref == frac);
+
+ std::cout << "frac = frac : ok" << std::endl;
+}
+
+void test_assignement_integer()
+{
+ const mln::algebra::frac<int> ref(-5,1);
+ mln::algebra::frac<int> frac;
+
+ frac = -5;
+ mln_assertion(ref == frac);
+
+ std::cout << "frac = integer : ok" << std::endl;
+}
+
+
+//
+// TEST COMPARAISON
+//
+void test_comparaison_equal_to()
+{
+ const mln::algebra::frac<int> op1(4,6);
+ const mln::algebra::frac<int> op2(6,4);
+
+ mln_assertion(op1 == op1);
+ mln_assertion(!(op1 == op2));
+
+ std::cout << "frac == frac : ok" << std::endl;
+}
+
+void test_comparaison_not_equal_to()
+{
+ const mln::algebra::frac<int> op1(4,6);
+ const mln::algebra::frac<int> op2(6,4);
+
+ mln_assertion(!(op1 != op1));
+ mln_assertion(op1 != op2);
+
+ std::cout << "frac != frac : ok" << std::endl;
+}
+
+void test_comparaison_less_equal_than()
+{
+ const mln::algebra::frac<int> op1(1,5);
+ const mln::algebra::frac<int> op2(2,5);
+
+ mln_assertion(op1 <= op2);
+ mln_assertion(op2 <= op2);
+ mln_assertion(!(op2 <= op1));
+
+ std::cout << "frac <= frac : ok" << std::endl;
+}
+
+void test_comparaison_less_than()
+{
+ const mln::algebra::frac<int> op1(1,5);
+ const mln::algebra::frac<int> op2(2,5);
+
+ mln_assertion(op1 < op2);
+ mln_assertion(!(op2 < op2));
+ mln_assertion(!(op2 < op1));
+
+ std::cout << "frac < frac : ok" << std::endl;
+}
+
+void test_comparaison_greater_than()
+{
+ const mln::algebra::frac<int> op1(2,5);
+ const mln::algebra::frac<int> op2(1,5);
+
+ mln_assertion(op1 > op2);
+ mln_assertion(!(op2 > op2));
+ mln_assertion(!(op2 > op1));
+
+ std::cout << "frac > frac : ok" << std::endl;
+}
+
+void test_comparaison_greater_equal_than()
+{
+ const mln::algebra::frac<int> op1(2,5);
+ const mln::algebra::frac<int> op2(1,5);
+
+ mln_assertion(op1 >= op2);
+ mln_assertion(op2 >= op2);
+ mln_assertion(!(op2 >= op1));
+
+ std::cout << "frac >= frac : ok" << std::endl;
+}
+
+//
+// TEST FRAC ARITHMETIC
+//
+void test_frac_arithmetic_uminus()
+{
+ const mln::algebra::frac<int> ref(-1,4);
+ const mln::algebra::frac<int> op1(1,4);
+
+ mln_assertion(ref == (-op1));
+ std::cout << "-frac : ok" << std::endl;
+}
+
+void test_frac_arithmetic_plus()
+{
+ const mln::algebra::frac<int> ref1(6,4);
+ const mln::algebra::frac<int> ref2(10,4);
+ const mln::algebra::frac<int> ref3(14,4);
+ const mln::algebra::frac<int> op1(2,4);
+ const mln::algebra::frac<int> op2(1,1);
+ mln::algebra::frac<int> res = op1;
+
+ res += op2;
+
+ mln_assertion(ref1 == (op1 + op2));
+ mln_assertion(ref1 == res);
+ mln_assertion(ref1 == (res++));
+ mln_assertion(ref2 == res);
+ mln_assertion(ref3 == (++res));
+ mln_assertion(ref3 == res);
+
+ std::cout << "frac + frac : ok" << std::endl;
+ std::cout << "frac += frac : ok" << std::endl;
+ std::cout << "frac++ : ok" << std::endl;
+ std::cout << "++frac : ok" << std::endl;
+}
+
+void test_frac_arithmetic_minus()
+{
+ const mln::algebra::frac<int> ref1(-1,4);
+ const mln::algebra::frac<int> ref2(-5,4);
+ const mln::algebra::frac<int> ref3(-9,4);
+ const mln::algebra::frac<int> op1(3,4);
+ const mln::algebra::frac<int> op2(1,1);
+ mln::algebra::frac<int> res = op1;
+
+ res -= op2;
+
+ mln_assertion(ref1 == (op1 - op2));
+ mln_assertion(ref1 == res);
+ mln_assertion(ref1 == (res--));
+ mln_assertion(ref2 == res);
+ mln_assertion(ref3 == (--res));
+ mln_assertion(ref3 == res);
+
+ std::cout << "frac - frac : ok" << std::endl;
+ std::cout << "frac -= frac : ok" << std::endl;
+ std::cout << "frac-- : ok" << std::endl;
+ std::cout << "--frac : ok" << std::endl;
+}
+
+void test_frac_arithmetic_times()
+{
+ const mln::algebra::frac<int> ref(3,8);
+ const mln::algebra::frac<int> op1(2,4);
+ const mln::algebra::frac<int> op2(3,4);
+ mln::algebra::frac<int> res = op1;
+
+ res *= op2;
+
+ mln_assertion(ref == (op1 * op2));
+ mln_assertion(ref == res);
+
+ std::cout << "frac * frac : ok" << std::endl;
+ std::cout << "frac *= frac : ok" << std::endl;
+}
+
+void test_frac_arithmetic_div()
+{
+ const mln::algebra::frac<int> ref(2,3);
+ const mln::algebra::frac<int> op1(2,4);
+ const mln::algebra::frac<int> op2(3,4);
+ mln::algebra::frac<int> res = op1;
+
+ res /= op2;
+
+ mln_assertion(ref == (op1 / op2));
+ mln_assertion(ref == res);
+
+ std::cout << "frac / frac : ok" << std::endl;
+ std::cout << "frac /= frac : ok" << std::endl;
+}
+
+//
+// TEST SCALAR ARITHMETIC
+//
+
+void test_scalar_arithmetic_plus()
+{
+ const mln::algebra::frac<int> ref(6,4);
+ const mln::algebra::frac<int> op1(2,4);
+ const int op2 = 1;
+ mln::algebra::frac<int> res = op1;
+
+ res += op2;
+
+ mln_assertion(ref == (op1 + op2));
+ mln_assertion(ref == res);
+
+ std::cout << "frac + integer : ok" << std::endl;
+ std::cout << "frac += integer : ok" << std::endl;
+}
+
+void test_scalar_arithmetic_minus()
+{
+ const mln::algebra::frac<int> ref1(-1,4);
+ const mln::algebra::frac<int> op1(3,4);
+ const int op2 = 1;
+ mln::algebra::frac<int> res = op1;
+
+ res -= op2;
+
+ mln_assertion(ref1 == (op1 - op2));
+ mln_assertion(ref1 == res);
+
+ std::cout << "frac - integer : ok" << std::endl;
+ std::cout << "frac -= integer : ok" << std::endl;
+}
+
+void test_scalar_arithmetic_times()
+{
+ const mln::algebra::frac<int> ref(6,4);
+ const mln::algebra::frac<int> op1(2,4);
+ const int op2 = 3;
+ mln::algebra::frac<int> res = op1;
+
+ res *= op2;
+
+ mln_assertion(ref == (op1 * op2));
+ mln_assertion(ref == res);
+
+ std::cout << "frac * integer : ok" << std::endl;
+ std::cout << "frac *= integer : ok" << std::endl;
+}
+
+void test_scalar_arithmetic_div()
+{
+ const mln::algebra::frac<int> ref(2,12);
+ const mln::algebra::frac<int> op1(2,4);
+ const int op2 = 3;
+ mln::algebra::frac<int> res = op1;
+
+ res /= op2;
+
+ mln_assertion(ref == (op1 / op2));
+ mln_assertion(ref == res);
+
+ std::cout << "frac / integer : ok" << std::endl;
+ std::cout << "frac /= integer : ok" << std::endl;
+}
+
+
+int main2()
+{
+ // TEST INSTANTIATION
+ std::cout << std::endl << "TEST INSTANTIATION" <<
std::endl;
+ test_instantiation_without_argument();
+ test_instantiation_numerator_denominator();
+ test_instantiation_frac();
+ test_instantiation_zero();
+ test_instantiation_one();
+ test_instantiation_integer();
+
+ // TEST FRAC_BASE
+ std::cout << std::endl << "TEST FRAC_BASE" << std::endl;
+ test_frac_base_accessor();
+ test_frac_base_manipulator();
+
+ // TEST ASSIGNEMENT
+ std::cout << std::endl << "TEST ASSIGNEMENT" << std::endl;
+ test_assignement_zero();
+ test_assignement_one();
+ test_assignement_frac();
+ test_assignement_integer();
+
+ // TEST COMPARAISON
+ std::cout << std::endl << "TEST COMPARAISON" << std::endl;
+ test_comparaison_equal_to();
+ test_comparaison_not_equal_to();
+ test_comparaison_less_equal_than();
+ test_comparaison_less_than();
+ test_comparaison_greater_equal_than();
+ test_comparaison_greater_than();
+
+ // TEST FRAC ARITHMETIC
+ std::cout << std::endl << "TEST FRAC ARITHMETIC" <<
std::endl;
+ test_frac_arithmetic_uminus();
+ test_frac_arithmetic_plus();
+ test_frac_arithmetic_minus();
+ test_frac_arithmetic_times();
+ test_frac_arithmetic_div();
+
+ // TEST SCALAR ARITHMETIC
+ std::cout << std::endl << "TEST SCALAR ARITHMETIC" <<
std::endl;
+ test_scalar_arithmetic_plus();
+ test_scalar_arithmetic_minus();
+ test_scalar_arithmetic_times();
+ test_scalar_arithmetic_div();
+
+ return 0;
+}
diff --git a/trunk/milena/sandbox/green/Fraction/frac.hh
b/trunk/milena/sandbox/green/fraction/frac.hh
similarity index 50%
rename from trunk/milena/sandbox/green/Fraction/frac.hh
rename to trunk/milena/sandbox/green/fraction/frac.hh
index b8ec226..d9f8c99 100644
--- a/trunk/milena/sandbox/green/Fraction/frac.hh
+++ b/trunk/milena/sandbox/green/fraction/frac.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2006, 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -26,7 +26,6 @@
#ifndef MLN_ALGEBRA_FRAC_HH
# define MLN_ALGEBRA_FRAC_HH
-// includes
#include <iostream>
#include <mln/core/concept/object.hh>
@@ -36,9 +35,8 @@
#include <mln/value/scalar.hh>
#include <mln/debug/format.hh>
-#include <mln/math/min.hh>
-#include <mln/math/max.hh>
#include <mln/math/abs.hh>
+#include <mln/math/sign.hh>
#include <mln/literal/zero.hh>
#include <mln/literal/one.hh>
@@ -46,6 +44,11 @@
#include <mln/trace/entering.hh>
#include <mln/trace/exiting.hh>
+#include <mln/value/int_u8.hh>
+
+#include "sign_prod.hh"
+#include "gcd.hh"
+
namespace mln
{
namespace algebra
@@ -62,6 +65,14 @@ namespace mln
struct one_t;
}
+ // FIXME : frac += scalar ... doesn't compile ...
+ // FIXME : Comment s'assurer que le type T ne contient que des non flottants
+ // de type entier ... ???
+ // FIXME : Comment trouver la fraction equivalente à un flottant
+ // FIXME : Comment enregistrer correctement les traits ??
+ // FIXME : Comment intégrer frac pour qu'il fonctionne avec la variance ??
+ // FIXME : Code experimental
+
namespace trait
{
template<typename T>
@@ -92,15 +103,37 @@ namespace mln
class frac_base_ : public Object< frac<T> >
{
private:
- T numerator_;
- T denominator_;
+ T numerator_;
+ T denominator_;
+ math::sign_t sign_;
public:
- const T& numerator(const T& numerator) {this->numerator_ = numerator;
return numerator;}
- const T& denominator(const T& denominator) {this->denominator_ =
denominator; return denominator;}
+ const T& numerator() const {return numerator_;}
+ const T& denominator() const {return denominator_;}
+ const math::sign_t& sign() const {return sign_;}
- const T& numerator() const {return numerator_;}
- const T& denominator() const {return denominator_;}
+ float eval() const
+ {
+ T sign = math::sign_to_coeff<T>(sign_);
+ float numerator = static_cast<float>(numerator_);
+ float denominator = static_cast<float>(denominator_);
+ float result = sign * numerator/denominator;
+
+ return result;
+ }
+
+ void irreducible(const T& numerator, const T& denominator)
+ {
+ trace::entering("mln::algebra::internal::frac_base_::irreducible");
+
+ T divisor = math::gcd(numerator, denominator);
+ this->sign_ = math::sign_prod<T>(numerator, denominator);
+ this->numerator_ = math::abs(numerator) / divisor;
+ this->denominator_ = math::abs(denominator) / divisor;
+
+ trace::exiting("mln::algebra::internal::frac_base_::irreducible");
+ }
+
};
} // end of namespace mln::algebra::internal
@@ -109,23 +142,21 @@ namespace mln
{
typedef internal::frac_base_<T> super_;
- private:
- const T gcd_(const T& a, const T& b) const;
-
public:
// Constructor without argument ==> very dangerous one in this context
frac();
// Constructor to convert scalar in fraction (transtyping)
+ template <typename S>
+ frac(const value::scalar_<S>& scalar);
frac(const T& scalar);
+ //frac(const value::int_u8& scalar);
// Constructor with literal zero
frac(const literal::zero_t& zero);
- frac& operator=(const literal::zero_t& zero);
// Constructor with literal one
frac(const literal::one_t& one);
- frac& operator=(const literal::one_t& one);
// Constructor setting the internal values
frac(const T& numerator_, const T& denominator_);
@@ -138,19 +169,13 @@ namespace mln
frac(const frac<F>& rhs);
// Assignement operator
+ frac& operator=(const literal::zero_t& zero);
+ frac& operator=(const literal::one_t& one);
frac& operator=(const frac<T>& rhs);
// Second assignement operator
template<typename F>
frac& operator=(const frac<F>& rhs);
-
- // Greatest common divisor (Euclidian Algorithm)
- const T gcd(const T& a, const T& b) const;
-
- const frac<T>& irreducible();
-
- // Return the quotient
- float eval() const;
};
} // end of namespace mln::algebra
@@ -165,26 +190,25 @@ namespace mln
};
- // - frac
- template <typename T>
- struct set_precise_unary_<op::uminus, algebra::frac<T> >
- {
- typedef mln_trait_op_uminus(T) V;
- typedef algebra::frac<V> ret;
- };
-
+ //
+ // SCALAR ARITHMETIC
+ //
+
// frac + s
template <typename T, typename S>
- struct set_precise_binary_<op::plus, algebra::frac<T>,
mln::value::scalar_<S> >
+ struct set_precise_binary_<op::plus,
+ algebra::frac<T>,
+ mln::value::scalar_<S> >
{
typedef mln_trait_op_plus(T, S) V;
typedef algebra::frac<V> ret;
};
-
// frac - s
template <typename T, typename S>
- struct set_precise_binary_<op::minus, algebra::frac<T>,
mln::value::scalar_<S> >
+ struct set_precise_binary_<op::minus,
+ algebra::frac<T>,
+ mln::value::scalar_<S> >
{
typedef mln_trait_op_minus(T, S) V;
typedef algebra::frac<V> ret;
@@ -193,7 +217,9 @@ namespace mln
// frac * s
template <typename T, typename S>
- struct set_precise_binary_<op::times, algebra::frac<T>,
mln::value::scalar_<S> >
+ struct set_precise_binary_<op::times,
+ algebra::frac<T>,
+ mln::value::scalar_<S> >
{
typedef mln_trait_op_times(T, S) V;
typedef algebra::frac<V> ret;
@@ -202,12 +228,18 @@ namespace mln
// frac / s
template <typename T, typename S>
- struct set_precise_binary_<op::div, algebra::frac<T>,
mln::value::scalar_<S> >
+ struct set_precise_binary_<op::div,
+ algebra::frac<T>,
+ mln::value::scalar_<S> >
{
typedef mln_trait_op_div(T, S) V;
typedef algebra::frac<V> ret;
};
+
+ //
+ // FRAC ARITHMETIC
+ //
// frac + frac
template <typename T, typename F>
@@ -231,7 +263,6 @@ namespace mln
template <typename T, typename F>
struct set_precise_binary_<op::times, algebra::frac<T>,
algebra::frac<F> >
{
- //typedef mln_sum_poduct(T, F) ret;
typedef mln_trait_op_times(T, F) V;
typedef algebra::frac<V> ret;
};
@@ -246,15 +277,49 @@ namespace mln
};
+ //
+ // COMPARAISON
+ //
+
+ // frac == frac
+ template <typename T, typename F>
+ struct set_precise_binary_<op::eq, algebra::frac<T>, algebra::frac<F>
>
+ {
+ typedef bool ret;
+ };
+
+ // frac < frac
+ template <typename T, typename F>
+ struct set_precise_binary_<op::less, algebra::frac<T>,
algebra::frac<F> >
+ {
+ typedef bool ret;
+ };
+
}// end of namespace mln::trait
namespace algebra
{
+ //
+ // COMPARAISON
+ //
+
+ template <typename T, typename F>
+ math::sign_t compare(const frac<T>& lhs, const frac<F>& rhs);
+
// frac == frac
template <typename T, typename F>
bool
operator==(const frac<T>& lhs, const frac<F>& rhs);
+ // frac < frac
+ template <typename T, typename F>
+ bool
+ operator<(const frac<T>& lhs, const frac<F>& rhs);
+
+ //
+ // INPUT/OUTPUT STREAM
+ //
+
// <<
template <typename T>
std::ostream&
@@ -265,10 +330,9 @@ namespace mln
std::istream&
operator<<(std::istream& istr, const frac<T>& rhs);
- // - frac
- template <typename T>
- frac<mln_trait_op_uminus(T)>
- operator-(const frac<T>& rhs);
+ //
+ // SCALAR ARITHMETIC
+ //
// frac + s
template <typename T, typename S>
@@ -290,6 +354,10 @@ namespace mln
frac<mln_trait_op_div(T,S)>
operator/(const frac<T>& lhs, const mln::value::scalar_<S>& s);
+ //
+ // FRAC ARITHMETIC
+ //
+
// frac + frac
template <typename T, typename F>
frac<mln_trait_op_plus(T,F)>
@@ -317,260 +385,226 @@ namespace mln
namespace algebra
{
+
+ //
+ // INSTANTIATION
+ //
template <typename T>
inline
frac<T>::frac() : super_()
{
- trace::entering("mln::algebra::frac<T>::frac()");
+ trace::entering("mln::algebra::frac<T>::frac");
- this->numerator(0);
- this->denominator(1);
+ this->irreducible(0, 1);
- trace::exiting("mln::algebra::frac<T>::frac()");
+ trace::exiting("mln::algebra::frac<T>::frac");
}
template <typename T>
frac<T>::frac(const T& scalar) : super_()
{
- trace::entering("mln::algebra::frac<T>::frac(const S&
scalar)");
+ trace::entering("mln::algebra::frac<T>::frac");
- this->numerator(scalar);
- this->denominator(1);
+ this->irreducible(scalar, 1);
- trace::exiting("mln::algebra::frac<T>::frac(const S&
scalar)");
+ trace::exiting("mln::algebra::frac<T>::frac");
}
-
+
template <typename T>
- inline
- frac<T>::frac(const T& numerator, const T& denominator) : super_()
+ template <typename S>
+ frac<T>::frac(const value::scalar_<S>& scalar) : super_()
{
- trace::entering("mln::algebra::frac<T>::frac(const T& numerator,
const T& denominator)");
-
- this->numerator(numerator);
- this->denominator(denominator);
-
- irreducible();
+ trace::entering("mln::algebra::frac<T>::frac");
+
+ this->irreducible(scalar, 1);
- trace::exiting("mln::algebra::frac<T>::frac(const T& numerator,
const T& denominator)");
+ trace::exiting("mln::algebra::frac<T>::frac");
}
-
+
template <typename T>
inline
- frac<T>::frac(const literal::zero_t& zero) : super_()
+ frac<T>::frac(const T& numerator, const T& denominator) : super_()
{
- trace::entering("mln::algebra::frac<T>::frac(const literal::zero_t&
zero)");
+ trace::entering("mln::algebra::frac<T>::frac");
- this->numerator(zero);
- this->denominator(1);
+ this->irreducible(numerator, denominator);
- trace::exiting("mln::algebra::frac<T>::frac(const literal::zero_t&
zero)");
+ trace::exiting("mln::algebra::frac<T>::frac");
}
template <typename T>
inline
- frac<T>& frac<T>::operator=(const literal::zero_t& zero)
+ frac<T>::frac(const literal::zero_t& zero) : super_()
{
- trace::entering("frac<T>&
mln::algebra::frac<T>::operator=(const literal::zero_t& zero)");
+ trace::entering("mln::algebra::frac<T>::frac");
- this->numerator(zero);
- this->denominator(1);
+ this->irreducible(zero, 1);
- trace::exiting("frac<T>&
mln::algebra::frac<T>::operator=(const literal::zero_t& zero)");
- return *this;
+ trace::exiting("mln::algebra::frac<T>::frac");
}
-
-
template <typename T>
inline
frac<T>::frac(const literal::one_t& one) : super_()
{
- trace::entering("frac<T>::frac(const literal::one_t& one)");
+ trace::entering("frac<T>::frac");
- this->numerator(one);
- this->denominator(1);
+ this->irreducible(one, 1);
- trace::exiting("frac<T>::frac(const literal::one_t& one)");
+ trace::exiting("frac<T>::frac");
}
template <typename T>
inline
- frac<T>& frac<T>::operator=(const literal::one_t& one)
+ frac<T>::frac(const frac<T>& rhs) : super_()
{
- trace::entering("frac<T>&
mln::algebra::frac<T>::operator=(const literal::one_t& one)");
-
- this->numerator(one);
- this->denominator(1);
+ trace::entering("mln::algebra::frac<T>::frac");
+
+ T rhs_sign = math::sign_to_coeff<T>(rhs.sign());
+
+ this->irreducible(rhs_sign*rhs.numerator(), rhs.denominator());
- trace::exiting("frac<T>&
mln::algebra::frac<T>::operator=(const literal::one_t& one)");
- return *this;
+ trace::exiting("mln::algebra::frac<T>::frac");
}
template <typename T>
+ template <typename F>
inline
- frac<T>::frac(const frac<T>& rhs) : super_()
+ frac<T>::frac(const frac<F>& rhs) : super_()
{
- trace::entering("mln::algebra::frac<T>::frac(const frac<T>&
rhs)");
+ trace::entering("mln::algebra::frac<T>::frac");
+ mlc_converts_to(F, T)::check();
- this->numerator(rhs.numerator());
- this->denominator(rhs.denominator());
+ T rhs_sign = math::sign_to_coeff<T>(rhs.sign());
+ T rhs_numerator = rhs_sign*static_cast<T>(rhs.numerator());
+ T rhs_denominator = static_cast<T>(rhs.denominator());
- irreducible();
+ this->irreducible(rhs_numerator, rhs_denominator);
- trace::exiting("mln::algebra::frac<T>::frac(const frac<T>&
rhs)");
+ trace::exiting("mln::algebra::frac<T>::frac");
}
-
+
+ //
+ // ASSIGNEMENT
+ //
+
template <typename T>
inline
frac<T>& frac<T>::operator=(const frac<T>& rhs)
{
- trace::entering("frac<T>&
mln::algebra::frac<T>::operator=(const frac<T>& rhs)");
-
- numerator(rhs.numerator());
- denominator(rhs.denominator());
+ trace::entering("mln::algebra::frac<T>::operator=");
+
+ T rhs_sign = math::sign_to_coeff<T>(rhs.sign());
- irreducible();
- trace::exiting("frac<T>& mln::algebra::frac<T>::operator=(const
frac<T>& rhs)");
+ this->irreducible(rhs_sign*rhs.numerator(), rhs.denominator());
+
+ trace::exiting("mln::algebra::frac<T>::operator=");
return *this;
}
template <typename T>
- template <typename F>
inline
- frac<T>::frac(const frac<F>& rhs) : super_()
+ frac<T>& frac<T>::operator=(const literal::one_t& one)
{
- trace::entering("mln::algebra::frac<T>::frac(const frac<F>&
rhs)");
- mlc_converts_to(F, T)::check();
-
- numerator(static_cast<T>(rhs.numerator()));
- denominator(static_cast<T>(rhs.denominator()));
+ trace::entering("mln::algebra::frac<T>::operator=");
- irreducible();
+ this->irreducible(one, 1);
- trace::exiting("mln::algebra::frac<T>::frac(const frac<F>&
rhs)");
+ trace::exiting("mln::algebra::frac<T>::operator=");
+ return *this;
}
template <typename T>
- template <typename F>
inline
- frac<T>& frac<T>::operator=(const frac<F>& rhs)
+ frac<T>& frac<T>::operator=(const literal::zero_t& zero)
{
- trace::entering("frac<T>&
mln::algebra::frac<T>::operator=(const frac<F>& rhs)");
- mlc_converts_to(F, T)::check();
+ trace::entering("mln::algebra::frac<T>::operator=");
- numerator(static_cast<T>(rhs.numerator()));
- denominator(static_cast<T>(rhs.denominator()));
-
- irreducible();
- trace::exiting("frac<T>& mln::algebra::frac<T>::operator=(const
frac<F>& rhs)");
+ this->irreducible(zero, 1);
+ trace::exiting("mln::algebra::frac<T>::operator=");
return *this;
}
- // Greatest common divisor (Euclidian algorithm)
template <typename T>
+ template <typename F>
inline
- const T frac<T>::gcd(const T& a, const T& b) const
+ frac<T>& frac<T>::operator=(const frac<F>& rhs)
{
- trace::entering("const T mln::algebra::frac<T>::gcd(const T& a,
const T& b)");
+ trace::entering("mln::algebra::frac<T>::operator=");
+ mlc_converts_to(F, T)::check();
- T result;
- T abs_a = math::abs(a);
- T abs_b = math::abs(b);
+ T rhs_sign = math::sign_to_coeff<T>(rhs.sign());
+ T rhs_numerator = rhs_sign*static_cast<T>(rhs.numerator());
+ T rhs_denominator = static_cast<T>(rhs.denominator());
- if ((0 == abs_a) || (0 == abs_b))
- result = 1;
- else
- result = gcd_(math::max(abs_a, abs_b), math::min(abs_a, abs_b));
+ this->irreducible(rhs_numerator, rhs_denominator);
+
+ trace::exiting("mln::algebra::frac<T>::operator=");
- trace::exiting("const T mln::algebra::frac<T>::gcd(const T& a, const
T& b)");
- return result;
+ return *this;
}
- template <typename T>
+ //
+ // COMPARAISON
+ //
+ template <typename T, typename F>
inline
- const T frac<T>::gcd_(const T& a, const T& b) const
+ math::sign_t compare(const frac<T>& lhs, const frac<F>& rhs)
{
- trace::entering("const T mln::algebra::frac<T>::cgd_(const T& a,
const T& b)");
- mln_assertion(a > 0);
- mln_assertion(b > 0);
- mln_assertion(a >= b);
-
- T rest = a%b;
+ trace::entering("mln::algebra::compare");
+ mlc_converts_to(F, T)::check();
- if (0 == rest)
- rest = b;
- else
- rest = gcd(b, rest);
+ T rhs_sign = math::sign_to_coeff<T>(rhs.sign());
+ T lhs_sign = math::sign_to_coeff<T>(lhs.sign());
+ T side1 = rhs_sign*lhs.numerator()*rhs.denominator();
+ T side2 = lhs_sign*rhs.numerator()*lhs.denominator();
+ math::sign_t result = math::sign(side1 - side2);
- trace::exiting("const T mln::algebra::frac<T>::cgd_(const T& a,
const T& b)");
- return rest;
+ trace::exiting("mln::algebra::compare");
+ return result;
}
- template <typename T>
+ template <typename T, typename F>
inline
- const frac<T>& frac<T>::irreducible()
+ bool operator==(const frac<T>& lhs, const frac<F>& rhs)
{
- trace::entering("frac<T>&
mln::algebra::frac<T>::irreducible()");
+ trace::entering("mln::algebra::operator==");
- const T& numerator = this->numerator();
- const T& denominator = this->denominator();
- T divisor = this->gcd(numerator, denominator);
+ bool result = is_null(compare(lhs, rhs));
- this->numerator(numerator/divisor);
- this->denominator(denominator/divisor);
-
- trace::exiting("frac<T>&
mln::algebra::frac<T>::irreducible()");
- return *this;
+ trace::exiting("mln::algebra::operator==");
+ return result;
}
-
- template <typename T>
- inline
- float frac<T>::eval() const
- {
- trace::entering("frac<T>&
mln::algebra::frac<T>::eval()");
- const T& numerator = super_::numerator();
- const T& denominator = super_::denominator();
-
- float float_num = static_cast<float>(numerator);
- float float_denom = static_cast<float>(denominator);
- float result = float_num / float_denom;
-
- trace::exiting("frac<T>&
mln::algebra::frac<T>::eval()");
- return result ;
- }
-
template <typename T, typename F>
inline
- bool operator==(const frac<T>& lhs, const frac<F>& rhs)
+ bool operator<(const frac<T>& lhs, const frac<F>& rhs)
{
- trace::entering("bool mln::algebra::operator==(const frac<T>& lhs,
const frac<F>& rhs)");
+ trace::entering("mln::algebra::operator<");
- frac<T> lhsi(lhs);
- frac<T> rhsi(rhs);
+ bool result = is_negative(compare(lhs, rhs));
- lhsi.irreducible();
- rhsi.irreducible();
+ trace::exiting("mln::algebra::operator<");
+ return result;
+ }
- bool same_numerator = lhsi.numerator() == rhsi.numerator();
- bool same_denominator = rhsi.denominator() == rhsi.denominator();
- bool result = same_numerator && same_denominator;
+ //
+ // INPUT/OUTPUT STREAM
+ //
- trace::exiting("bool mln::algebra::operator==(const frac<T>& lhs,
const frac<F>& rhs)");
- return result;
- }
-
template <typename T>
std::ostream&
operator<<(std::ostream& ostr, const frac<T>& rhs)
{
- trace::entering("std::ostream&
mln::algebra::operator<<(std::ostream& ostr, const frac<T>&
rhs)");
+ trace::entering("mln::algebra::operator<<");
- ostr << '(' << debug::format(rhs.numerator()) <<
'/' << debug::format(rhs.denominator()) << ')';
+ ostr << (math::is_negative(rhs.sign())? '-' : '+');
+ ostr << '(' << debug::format(rhs.numerator());
+ ostr << '/' << debug::format(rhs.denominator()) <<
')';
- trace::exiting("std::ostream&
mln::algebra::operator<<(std::ostream& ostr, const frac<T>&
rhs)");
+ trace::exiting("mln::algebra::operator<<");
return ostr;
}
@@ -578,48 +612,116 @@ namespace mln
std::istream&
operator>>(std::istream& istr, const frac<T>& rhs)
{
- trace::entering("std::istream&
mln::algebra::operator>>(std::istream& istr, const frac<T>&
rhs)");
+ trace::entering("mln::algebra::operator>>");
istr >> rhs.numerator();
istr >> rhs.denominator();
- trace::exiting("std::istream&
mln::algebra::operator>>(std::istream& istr, const frac<T>&
rhs)");
+ trace::exiting("mln::algebra::operator>>");
return istr;
}
- // - frac
- template <typename T>
- frac<mln_trait_op_uminus(T)>
- operator-(const frac<T>& lhs)
+ //
+ // FRAC ARITHMETIC
+ //
+
+ // frac + frac
+ template <typename T, typename F>
+ frac<mln_trait_op_plus(T,F)>
+ operator+(const frac<T>& lhs, const frac<F>& rhs)
{
- trace::entering("frac<mln_trait_op_uminus(T)>
mln::algebra::operator-(const frac<T>& lhs)");
- typedef mln_trait_op_uminus(T) R;
- frac<R> tmp = lhs;
-
- tmp.numerator(-lhs.numerator());
- tmp.denominator(lhs.denominator());
+ trace::entering("mln::algebra::operator+");
+ typedef mln_trait_op_plus(T,F) R;
+
+ R rhs_sign = math::sign_to_coeff<R>(rhs.sign());
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R side1 = lhs_sign*lhs.numerator()*rhs.denominator();
+ R side2 = rhs_sign*rhs.numerator()*lhs.denominator();
+ R numerator = side1 + side2;
+ R denominator = lhs.denominator()*rhs.denominator();
+ frac<R> tmp(numerator, denominator);
- tmp.irreducible();
+ trace::exiting("mln::algebra::operator+");
+ return tmp;
+ }
+
+ // frac - frac
+ template <typename T, typename F>
+ frac<mln_trait_op_minus(T,F)>
+ operator-(const frac<T>& lhs, const frac<F>& rhs)
+ {
+ trace::entering("mln::algebra::operator-");
+ typedef mln_trait_op_minus(T,F) R;
+
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R rhs_sign = math::sign_to_coeff<R>(rhs.sign());
+ R side1 = lhs_sign*lhs.numerator()*rhs.denominator();
+ R side2 = rhs_sign*rhs.numerator()*lhs.denominator();
+ R numerator = side1 - side2;
+ R denominator = lhs.denominator()*rhs.denominator();
+ frac<R> tmp(numerator, denominator);
- trace::exiting("frac<mln_trait_op_uminus(T)>
mln::algebra::operator-(const frac<T>& lhs)");
+ trace::exiting("mln::algebra::operator-");
return tmp;
}
+ // frac * frac
+ template <typename T, typename F>
+ frac<mln_trait_op_times(T,F)>
+ operator*(const frac<T>& lhs, const frac<F>& rhs)
+ {
+ trace::entering("mln::algebra::operator*");
+ typedef mln_trait_op_times(T,F) R;
+
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R rhs_sign = math::sign_to_coeff<R>(rhs.sign());
+ R numerator = lhs_sign*lhs.numerator()*rhs.numerator();
+ R denominator = rhs_sign*lhs.denominator()*rhs.denominator();
+ frac<R> tmp(numerator, denominator);
+
+ trace::exiting("mln::algebra::operator*");
+ return tmp;
+ }
+
+ // frac / frac
+ template <typename T, typename F>
+ frac<mln_trait_op_div(T,F)>
+ operator/(const frac<T>& lhs, const frac<F>& rhs)
+ {
+ trace::entering("mln::algebra::operator/");
+ typedef mln_trait_op_div(T,F) R;
+
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R rhs_sign = math::sign_to_coeff<R>(rhs.sign());
+ R numerator = lhs_sign*lhs.numerator()*rhs.denominator();
+ R denominator = rhs_sign*lhs.denominator()*rhs.numerator();
+ frac<R> tmp(numerator, denominator);
+
+ trace::exiting("mln::algebra::operator/");
+ return tmp;
+ }
+
+ //
+ // SCALAR ARITHMETIC
+ //
+
// frac + s
template <typename T, typename S>
frac<mln_trait_op_plus(T,S)>
operator+(const frac<T>& lhs, const value::scalar_<S>& s)
{
- trace::entering("frac<mln_trait_op_plus(T,S)>
mln::algebra::operator+(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::entering("mln::algebra::operator+");
typedef mln_trait_op_plus(T,S) R;
- frac<R> tmp = lhs;
-
- tmp.numerator(lhs.numerator() + s.to_equiv() * lhs.denominator());
- tmp.denominator(lhs.denominator());
- tmp.irreducible();
+ R scalar = static_cast<R>(s.to_equiv());
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R side1 = lhs_sign * lhs.numerator();
+ R side2 = scalar * lhs.denominator();
+ R numerator = side1 + side2;
+ R denominator = lhs.denominator();
+ frac<R> tmp(numerator, denominator);
- trace::exiting("frac<mln_trait_op_plus(T,S)>
mln::algebra::operator+(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::exiting("mln::algebra::operator+");
return tmp;
}
@@ -628,16 +730,18 @@ namespace mln
frac<mln_trait_op_minus(T,S)>
operator-(const frac<T>& lhs, const value::scalar_<S>& s)
{
- trace::entering("frac<mln_trait_op_minus(T,S)>
mln::algebra::operator-(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::entering("mln::algebra::operator-");
typedef mln_trait_op_minus(T,S) R;
- frac<R> tmp = lhs;
-
- tmp.numerator(lhs.numerator() - s.to_equiv() * lhs.denominator());
- tmp.denominator(lhs.denominator());
- tmp.irreducible();
+ R scalar = static_cast<R>(s.to_equiv());
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R side1 = lhs_sign * lhs.numerator();
+ R side2 = scalar * lhs.denominator();
+ R numerator = side1 - side2;
+ R denominator = lhs.denominator();
+ frac<R> tmp(numerator, denominator);
- trace::exiting("frac<mln_trait_op_minus(T,S)>
mln::algebra::operator-(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::exiting("mln::algebra::operator-");
return tmp;
}
@@ -646,22 +750,16 @@ namespace mln
frac<mln_trait_op_times(T,S)>
operator*(const frac<T>& lhs, const value::scalar_<S>& s)
{
- trace::entering("frac<mln_trait_op_times(T,S)>
mln::algebra::operator*(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::entering("mln::algebra::operator*");
typedef mln_trait_op_times(T,S) R;
- frac<R> tmp = lhs;
-
- std::cout << tmp << std::endl;
- tmp.numerator(lhs.numerator() * s.to_equiv());
- tmp.denominator(lhs.denominator());
+ R scalar = static_cast<R>(s.to_equiv());
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R numerator = lhs_sign * lhs.numerator() * scalar;
+ R denominator = lhs.denominator();
+ frac<R> tmp(numerator, denominator);
- std::cout << tmp << std::endl;
-
- tmp.irreducible();
-
- std::cout << tmp << std::endl;
-
- trace::exiting("frac<mln_trait_op_times(T,S)>
mln::algebra::operator*(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::exiting("mln::algebra::operator*");
return tmp;
}
@@ -670,96 +768,19 @@ namespace mln
frac<mln_trait_op_div(T,S)>
operator/(const frac<T>& lhs, const value::scalar_<S>& s)
{
- trace::entering("frac<mln_trait_op_div(T,S)>
mln::algebra::operator/(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::entering("mln::algebra::operator/");
typedef mln_trait_op_div(T,S) R;
- frac<R> tmp = lhs;
-
- std::cout << tmp << std::endl;
-
- tmp.numerator(lhs.numerator());
- tmp.denominator(lhs.denominator() * s.to_equiv());
-
- std::cout << tmp << std::endl;
-
- tmp.irreducible();
- std::cout << tmp << std::endl;
+ R scalar = static_cast<R>(s.to_equiv());
+ R lhs_sign = math::sign_to_coeff<R>(lhs.sign());
+ R numerator = lhs_sign * lhs.numerator();
+ R denominator = lhs.denominator() * scalar;
+ frac<R> tmp(numerator, denominator);
- trace::exiting("frac<mln_trait_op_div(T,S)>
mln::algebra::operator/(const frac<T>& lhs, value::scalar<S>&
s)");
+ trace::exiting("mln::algebra::operator/");
return tmp;
}
- // frac + frac
- template <typename T, typename F>
- frac<mln_trait_op_plus(T,F)>
- operator+(const frac<T>& lhs, const frac<F>& rhs)
- {
- trace::entering("frac<mln_trait_op_plus(T,F)>
mln::algebra::operator+(const frac<T>& lhs, const frac<F>&
rhs)");
- typedef mln_trait_op_plus(T,F) R;
- frac<R> tmp;
-
- tmp.numerator(lhs.numerator()*rhs.denominator() +
lhs.denominator()*rhs.numerator());
- tmp.denominator(lhs.denominator()*rhs.denominator());
-
- tmp.irreducible();
-
- trace::exiting("frac<mln_trait_op_plus(T,F)>
mln::algebra::operator+(const frac<T>& lhs, const frac<F>&
rhs)");
- return tmp;
- }
-
- // frac - frac
- template <typename T, typename F>
- frac<mln_trait_op_minus(T,F)>
- operator-(const frac<T>& lhs, const frac<F>& rhs)
- {
- trace::entering("frac<mln_trait_op_minus(T,F)>
mln::algebra::operator-(const frac<T>& lhs, const frac<F>&
rhs)");
- typedef mln_trait_op_minus(T,F) R;
- frac<R> tmp;
-
- tmp.numerator(lhs.numerator()*rhs.denominator() -
lhs.denominator()*rhs.numerator());
- tmp.denominator(lhs.denominator()*rhs.denominator());
-
- tmp.irreducible();
-
- trace::exiting("frac<mln_trait_op_minus(T,F)>
mln::algebra::operator-(const frac<T>& lhs, const frac<F>&
rhs)");
- return tmp;
- }
-
- // frac * frac
- template <typename T, typename F>
- frac<mln_trait_op_times(T,F)>
- operator*(const frac<T>& lhs, const frac<F>& rhs)
- {
- trace::entering("frac<mln_trait_op_times(T,F)>
mln::algebra::operator*(const frac<T>& lhs, const frac<F>&
rhs)");
- typedef mln_trait_op_times(T,F) R;
- frac<R> tmp;
-
- tmp.numerator(lhs.numerator()*rhs.numerator());
- tmp.denominator(lhs.denominator()*rhs.denominator());
-
- tmp.irreducible();
-
- trace::exiting("frac<mln_trait_op_times(T,F)>
mln::algebra::operator*(const frac<T>& lhs, const frac<F>&
rhs)");
- return tmp;
- }
-
- // frac / frac
- template <typename T, typename F>
- frac<mln_trait_op_div(T,F)>
- operator/(const frac<T>& lhs, frac<F>& rhs)
- {
- trace::entering("frac<mln_trait_op_div(T,F)>
mln::algebra::operator/(const frac<T>& lhs, const frac<F>&
rhs)");
- typedef mln_trait_op_div(T,F) R;
- frac<R> tmp;
-
- tmp.numerator(lhs.numerator()*rhs.denominator());
- tmp.denominator(lhs.denominator()*rhs.numerator());
-
- tmp.irreducible();
-
- trace::exiting("frac<mln_trait_op_div(T,F)>
mln::algebra::operator/(const frac<T>& lhs, const frac<F>&
rhs)");
- return tmp;
- }
} // end of namespace mln::algebra
diff --git a/trunk/milena/sandbox/green/fraction/gcd.hh
b/trunk/milena/sandbox/green/fraction/gcd.hh
new file mode 100644
index 0000000..b087d71
--- /dev/null
+++ b/trunk/milena/sandbox/green/fraction/gcd.hh
@@ -0,0 +1,91 @@
+// Copyright (C) 2006, 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MATH_GCD_HH
+# define MLN_MATH_GCD_HH
+
+#include <mln/math/min.hh>
+#include <mln/math/max.hh>
+#include <mln/math/abs.hh>
+
+namespace mln
+{
+ namespace math
+ {
+ template <typename T>
+ T gcd(const T& a, const T& b);
+
+ template <typename T>
+ T gcd_(const T& a, const T& b);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Safety interface for the greatest common divisor
+ template <typename T>
+ inline
+ T gcd(const T& a, const T& b)
+ {
+ trace::entering("const T mln::math::gcd(const T& a, const T&
b)");
+
+ T result;
+ T abs_a = math::abs(a);
+ T abs_b = math::abs(b);
+
+ if ((0 == abs_a) || (0 == abs_b))
+ result = 1;
+ else
+ result = gcd_(math::max(abs_a, abs_b), math::min(abs_a, abs_b));
+
+ trace::exiting("const T mln::math::gcd(const T& a, const T&
b)");
+ return result;
+ }
+
+ // Euclidian algorithm for the greatest common divisor
+ template <typename T>
+ inline
+ T gcd_(const T& a, const T& b)
+ {
+ trace::entering("T mln::math::cgd_(const T& a, const T& b)");
+ mln_assertion(a > 0);
+ mln_assertion(b > 0);
+ mln_assertion(a >= b);
+
+ T rest = a%b;
+
+ if (0 == rest)
+ rest = b;
+ else
+ rest = gcd_(b, rest);
+
+ trace::exiting("T mln::math::cgd_(const T& a, const T& b)");
+ return rest;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ }
+}
+
+#endif // ! MLN_MATH_GCD_HH
diff --git a/trunk/milena/sandbox/green/fraction/sign_prod.hh
b/trunk/milena/sandbox/green/fraction/sign_prod.hh
new file mode 100644
index 0000000..b081904
--- /dev/null
+++ b/trunk/milena/sandbox/green/fraction/sign_prod.hh
@@ -0,0 +1,74 @@
+// Copyright (C) 2006, 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MATH_SIGN_PROD_HH
+# define MLN_MATH_SIGN_PROD_HH
+
+#include <mln/math/sign.hh>
+
+namespace mln
+{
+
+ namespace math
+ {
+ template <typename T>
+ sign_t sign_prod(const T& a, const T& b);
+
+ template <typename T>
+ T sign_to_coeff(const sign_t& s);
+
+ sign_t sign_prod_(const sign_t& a, const sign_t& b);
+
+ bool is_positive(const sign_t& s);
+ bool is_negative(const sign_t& s);
+ bool is_positive_or_null(const sign_t& s);
+ bool is_negative_or_null(const sign_t& s);
+ bool is_null(const sign_t& s);
+ bool is_not_null(const sign_t& s);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ sign_t sign_prod(const T& a, const T& b) {return
sign_prod_(math::sign(a), math::sign(b));}
+
+ template <typename T>
+ T sign_to_coeff(const sign_t& s) {return
static_cast<T>(s);}
+
+
+ sign_t sign_prod_(const sign_t& a, const sign_t& b){return
static_cast<sign_t>(a*b); }
+
+ bool is_positive(const sign_t& s) {return 0 < s;}
+ bool is_negative(const sign_t& s) {return 0 > s;}
+ bool is_positive_or_null(const sign_t& s) {return 0 <= s;}
+ bool is_negative_or_null(const sign_t& s) {return 0 >= s;}
+ bool is_null(const sign_t& s) {return 0 == s;}
+ bool is_not_null(const sign_t& s) {return 0 != s;}
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ }
+}
+
+#endif // ! MLN_MATH_SIGN_PROD_HH
--
1.5.6.5