
* 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