<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include <bse/bsemain.hh>
// #define TEST_VERBOSE
#include <bse/testing.hh>
#include <bse/bsemathsignal.hh>
#include <bse/bsecxxplugin.hh> // for generated types
#include "jsonipc/testjsonipc.cc" // test_jsonipc
#include <bse/signalmath.hh>

static void
test_jsonipc_functions()
{
  test_jsonipc();
}
TEST_ADD (test_jsonipc_functions);

using namespace Bse;

#define	FLF	"26.20"

static void
check_cent_tune_fast (void)
{
  // Cent Tune Function (fast Table based implementation)
  const double epsilon = 1e-15;
  for (int i = -100; i <= +100; i++)
    {
      double setpoint = pow (2.0, 1. / 1200. * i);
      TCMP (fabs (bse_cent_tune_fast (i) - setpoint), <, epsilon);
      if (i % 13 == 0)
        TOK();
    }
}
TEST_ADD (check_cent_tune_fast);

static void
check_cent_tune (void)
{
  // Cent Tune Function
  const double epsilon = 1e-14;
  int i = 0;
  for (double fine_tune = -3600; fine_tune < 3600; fine_tune += g_random_double())  /* 3 octaves */
    {
      double expected = pow (2.0, 1. / 1200. * fine_tune);
      TCMP (fabs (bse_cent_tune (fine_tune) - expected), <, epsilon);
      if (i++ % 500 == 0)
        TOK();
    }
}
TEST_ADD (check_cent_tune);

static void
check_equal_tempered_tuning (void)
{
  const double *table = bse_semitone_table_from_tuning (Bse::MusicalTuning::OD_12_TET); /* returns [-132..+132] */
  const double epsilon = 1e-11;
  for (int i = -132; i <= +132; i++)
    {
      double setpoint = pow (2.0, 1. / 12. * i);
      TCMP (fabs (table[i] - setpoint), <, epsilon);
      if (i % 13 == 0)
        TOK();
    }
}
TEST_ADD (check_equal_tempered_tuning);

static void
check_tuning_monotony (Bse::MusicalTuning musical_tuning)
{
  const double *table = bse_semitone_table_from_tuning (musical_tuning); /* returns [-132..+132] */
  for (int i = -132; i <= +132; i++)
    if (ABS (i) != 132)
      {
        TCMP (table[i - 1], <, table[i]);
        TCMP (table[i + 1], >, table[i]);
        if (i % 13 == 0)
          TOK();
      }
}

static void
check_freq_vs_notes (Bse::MusicalTuning musical_tuning)
{
  /* check freq/note mapping */
  for (int j = BSE_MIN_NOTE; j <= BSE_MAX_NOTE; j++)
    {
      for (int k = BSE_MIN_FINE_TUNE / 2; k <= BSE_MAX_FINE_TUNE / 2; k++)
        {
          double f, freq = bse_note_to_tuned_freq (musical_tuning, j, k);
          int note, fine_tune;
          int verbose = 0;
          if (verbose)
            printout ("compose  : note=%4d fine_tune=%4d freq=%" FLF "f\n", j, k, freq);
          f = freq;
          note = bse_note_from_freq (musical_tuning, freq);
          TASSERT (note != BSE_NOTE_VOID);
          fine_tune = bse_note_fine_tune_from_note_freq (musical_tuning, note, freq);
          freq = bse_note_to_tuned_freq (musical_tuning, note, fine_tune);
          double freq_error = freq - f;
          double freq_ratio = MAX (freq, f) / MIN (freq, f);
          if (verbose)
            printout ("decompose: note=%4d fine_tune=%4d freq=%" FLF "f   (diff=%" FLF "f)\n", note, fine_tune, freq, freq - f);
          if (ABS (k) < 11)
            TASSERT (note == j);
          if (musical_tuning == Bse::MusicalTuning::OD_12_TET)
            TCMP (fabs (freq_error), <, 0.00000000001);   /* equal temperament is fairly accurate */
          else
            TCMP (freq_ratio, <, 1.00057778950655485930); /* detuning should be smaller than a cent */
        }
      if (j % 3 == 0)
        TOK();
    }
}

static void
test_math_bits ()
{
  TCMP (bse_string_from_double (-1.0), ==, "-1.0");
  TCMP (bse_string_from_double (0.0), ==, "0.0");
  TCMP (bse_string_from_double (1000000000000000.75000000000000), ==, "1000000000000000.75");
  BseComplex c[] = { { 0, 0 }, { -1, +1 }, { +2, -3 } };
  const std::string c0 = bse_complex_str (c[0]);
  TCMP (c0, ==, "{0.0, 0.0}");
  const std::string c1 = bse_complex_str (c[1]);
  TCMP (c1, ==, "{-1.0, 1.0}");
  const std::string c2 = bse_complex_str (c[2]);
  TCMP (c2, ==, "{2.0, -3.0}");
  const std::string complex_list = bse_complex_list (BSE_ARRAY_SIZE (c), c, "");
  TCMP (complex_list, ==, "0.0 0.0\n-1.0 1.0\n2.0 -3.0\n");
  double a[] = { 0, -1, +2, -3, +7.75, -1000000000000000.75 };
  const std::string poly1 = bse_poly_str (BSE_ARRAY_SIZE (a) - 1, a, "x");
  TCMP (poly1, ==, "(0.0+x*(-1.0+x*(2.0+x*(-3.0+x*(7.75+x*(-1000000000000000.75))))))");
  const std::string poly2 = bse_poly_str1 (BSE_ARRAY_SIZE (a) - 1, a, "y");
  TCMP (poly2, ==, "(-1.0*y + 2.0*y**2 + -3.0*y**3 + 7.75*y**4 + -1000000000000000.75*y**5)");
}
TEST_ADD (test_math_bits);

static void
check_monotonic_tuning()
{
  const int64 last_tuning = int (Bse::MusicalTuning::YOUNG);
  /* check last tuning value by asserting defaulting behavior of succeding values */
  TCMP (bse_semitone_table_from_tuning (Bse::MusicalTuning (last_tuning + 1)),
        ==,
        bse_semitone_table_from_tuning (Bse::MusicalTuning (0)));
  /* check monotonic musical tuning systems */
  for (int j = int (Bse::MusicalTuning::OD_12_TET); j <= last_tuning; j++)
    {
      Bse::MusicalTuning musical_tuning = Bse::MusicalTuning (j);
      check_tuning_monotony (musical_tuning);
      check_freq_vs_notes (musical_tuning);
      TPASS ("Tuning System: %s\n", Aida::enum_value_to_short_string (musical_tuning));
    }
}
TEST_ADD (check_monotonic_tuning);

static void
fast_math_test()
{
  float f;
  double d;
  // check proper Inf and NaN handling (depends on compiler flags)
  f = d = .5 * INFINITY; TASSERT (d > 0 && f > 0 && std::isinf (f) && std::isinf (d));
  f = d = -3 * INFINITY; TASSERT (d < 0 && f < 0 && std::isinf (f) && std::isinf (d));
  f = f - f;            TASSERT (!(f == f) && std::isnan (f));  // Infinity - Infinity yields NaN
  d = 0.0 / 0.0;        TASSERT (!(d == d) && std::isnan (d));
  // check rounding
  TASSERT (int (+0.40) == +0.0 && Bse::irintf (+0.40) == +0.0);
  TASSERT (int (-0.40) == -0.0 && Bse::irintf (-0.40) == -0.0);
  TASSERT (int (+0.51) == +0.0 && Bse::irintf (+0.51) == +1.0);
  TASSERT (int (-0.51) == -0.0 && Bse::irintf (-0.51) == -1.0);
  TASSERT (int (+1.90) == +1.0 && Bse::irintf (+1.90) == +2.0);
  TASSERT (int (-1.90) == -1.0 && Bse::irintf (-1.90) == -2.0);
  // check fast_exp2(int), 2^(-126..+127) must be calculated with 0 error
  volatile float m = 1.0, p = 1.0;
  for (ssize_t i = 0; i <= 127; i++)
    {
      // Bse::printerr ("2^±%-3d = %15.10g, %-.14g\n", i, fast_exp2 (i), fast_exp2 (-i));
      TASSERT (fast_exp2 (i) == p);
      if (i != 127)
        TASSERT (fast_exp2 (-i) == m);
      else
        TASSERT (fast_exp2 (-i) <= m); // single precision result for 2^-127 is 0 or subnormal
      p *= 2;
      m /= 2;
    }
  // check fast_exp2 error margin in [-1..+1]
  const double step = Bse::Test::slow() ? 0.0000001 : 0.0001;
  for (double d = -1; d <= +1; d += step)
    {
      const double r = std::exp2 (d);
      const double err = std::fabs (r - fast_exp2 (d));
      TASSERT (err < 4e-7);
    }
}
TEST_ADD (fast_math_test);

#if 0
int
main (gint   argc,
      gchar *argv[])
{
  bse_init_test (&argc, argv);
  test_math_bits();
  check_cent_tune();
  check_cent_tune_fast();
  check_equal_tempered_tuning();
  check_monotonic_tuning();
  return 0;
}
#endif
<commit_msg>TESTS: misctests: fast_math_bench: benchmark various exp2f() impls<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include <bse/bsemain.hh>
// #define TEST_VERBOSE
#include <bse/testing.hh>
#include <bse/bsemathsignal.hh>
#include <bse/bsecxxplugin.hh> // for generated types
#include "jsonipc/testjsonipc.cc" // test_jsonipc
#include <bse/signalmath.hh>

static void
test_jsonipc_functions()
{
  test_jsonipc();
}
TEST_ADD (test_jsonipc_functions);

using namespace Bse;

#define	FLF	"26.20"

static void
check_cent_tune_fast (void)
{
  // Cent Tune Function (fast Table based implementation)
  const double epsilon = 1e-15;
  for (int i = -100; i <= +100; i++)
    {
      double setpoint = pow (2.0, 1. / 1200. * i);
      TCMP (fabs (bse_cent_tune_fast (i) - setpoint), <, epsilon);
      if (i % 13 == 0)
        TOK();
    }
}
TEST_ADD (check_cent_tune_fast);

static void
check_cent_tune (void)
{
  // Cent Tune Function
  const double epsilon = 1e-14;
  int i = 0;
  for (double fine_tune = -3600; fine_tune < 3600; fine_tune += g_random_double())  /* 3 octaves */
    {
      double expected = pow (2.0, 1. / 1200. * fine_tune);
      TCMP (fabs (bse_cent_tune (fine_tune) - expected), <, epsilon);
      if (i++ % 500 == 0)
        TOK();
    }
}
TEST_ADD (check_cent_tune);

static void
check_equal_tempered_tuning (void)
{
  const double *table = bse_semitone_table_from_tuning (Bse::MusicalTuning::OD_12_TET); /* returns [-132..+132] */
  const double epsilon = 1e-11;
  for (int i = -132; i <= +132; i++)
    {
      double setpoint = pow (2.0, 1. / 12. * i);
      TCMP (fabs (table[i] - setpoint), <, epsilon);
      if (i % 13 == 0)
        TOK();
    }
}
TEST_ADD (check_equal_tempered_tuning);

static void
check_tuning_monotony (Bse::MusicalTuning musical_tuning)
{
  const double *table = bse_semitone_table_from_tuning (musical_tuning); /* returns [-132..+132] */
  for (int i = -132; i <= +132; i++)
    if (ABS (i) != 132)
      {
        TCMP (table[i - 1], <, table[i]);
        TCMP (table[i + 1], >, table[i]);
        if (i % 13 == 0)
          TOK();
      }
}

static void
check_freq_vs_notes (Bse::MusicalTuning musical_tuning)
{
  /* check freq/note mapping */
  for (int j = BSE_MIN_NOTE; j <= BSE_MAX_NOTE; j++)
    {
      for (int k = BSE_MIN_FINE_TUNE / 2; k <= BSE_MAX_FINE_TUNE / 2; k++)
        {
          double f, freq = bse_note_to_tuned_freq (musical_tuning, j, k);
          int note, fine_tune;
          int verbose = 0;
          if (verbose)
            printout ("compose  : note=%4d fine_tune=%4d freq=%" FLF "f\n", j, k, freq);
          f = freq;
          note = bse_note_from_freq (musical_tuning, freq);
          TASSERT (note != BSE_NOTE_VOID);
          fine_tune = bse_note_fine_tune_from_note_freq (musical_tuning, note, freq);
          freq = bse_note_to_tuned_freq (musical_tuning, note, fine_tune);
          double freq_error = freq - f;
          double freq_ratio = MAX (freq, f) / MIN (freq, f);
          if (verbose)
            printout ("decompose: note=%4d fine_tune=%4d freq=%" FLF "f   (diff=%" FLF "f)\n", note, fine_tune, freq, freq - f);
          if (ABS (k) < 11)
            TASSERT (note == j);
          if (musical_tuning == Bse::MusicalTuning::OD_12_TET)
            TCMP (fabs (freq_error), <, 0.00000000001);   /* equal temperament is fairly accurate */
          else
            TCMP (freq_ratio, <, 1.00057778950655485930); /* detuning should be smaller than a cent */
        }
      if (j % 3 == 0)
        TOK();
    }
}

static void
test_math_bits ()
{
  TCMP (bse_string_from_double (-1.0), ==, "-1.0");
  TCMP (bse_string_from_double (0.0), ==, "0.0");
  TCMP (bse_string_from_double (1000000000000000.75000000000000), ==, "1000000000000000.75");
  BseComplex c[] = { { 0, 0 }, { -1, +1 }, { +2, -3 } };
  const std::string c0 = bse_complex_str (c[0]);
  TCMP (c0, ==, "{0.0, 0.0}");
  const std::string c1 = bse_complex_str (c[1]);
  TCMP (c1, ==, "{-1.0, 1.0}");
  const std::string c2 = bse_complex_str (c[2]);
  TCMP (c2, ==, "{2.0, -3.0}");
  const std::string complex_list = bse_complex_list (BSE_ARRAY_SIZE (c), c, "");
  TCMP (complex_list, ==, "0.0 0.0\n-1.0 1.0\n2.0 -3.0\n");
  double a[] = { 0, -1, +2, -3, +7.75, -1000000000000000.75 };
  const std::string poly1 = bse_poly_str (BSE_ARRAY_SIZE (a) - 1, a, "x");
  TCMP (poly1, ==, "(0.0+x*(-1.0+x*(2.0+x*(-3.0+x*(7.75+x*(-1000000000000000.75))))))");
  const std::string poly2 = bse_poly_str1 (BSE_ARRAY_SIZE (a) - 1, a, "y");
  TCMP (poly2, ==, "(-1.0*y + 2.0*y**2 + -3.0*y**3 + 7.75*y**4 + -1000000000000000.75*y**5)");
}
TEST_ADD (test_math_bits);

static void
check_monotonic_tuning()
{
  const int64 last_tuning = int (Bse::MusicalTuning::YOUNG);
  /* check last tuning value by asserting defaulting behavior of succeding values */
  TCMP (bse_semitone_table_from_tuning (Bse::MusicalTuning (last_tuning + 1)),
        ==,
        bse_semitone_table_from_tuning (Bse::MusicalTuning (0)));
  /* check monotonic musical tuning systems */
  for (int j = int (Bse::MusicalTuning::OD_12_TET); j <= last_tuning; j++)
    {
      Bse::MusicalTuning musical_tuning = Bse::MusicalTuning (j);
      check_tuning_monotony (musical_tuning);
      check_freq_vs_notes (musical_tuning);
      TPASS ("Tuning System: %s\n", Aida::enum_value_to_short_string (musical_tuning));
    }
}
TEST_ADD (check_monotonic_tuning);

static void
fast_math_test()
{
  float f;
  double d;
  // check proper Inf and NaN handling (depends on compiler flags)
  f = d = .5 * INFINITY; TASSERT (d > 0 && f > 0 && std::isinf (f) && std::isinf (d));
  f = d = -3 * INFINITY; TASSERT (d < 0 && f < 0 && std::isinf (f) && std::isinf (d));
  f = f - f;            TASSERT (!(f == f) && std::isnan (f));  // Infinity - Infinity yields NaN
  d = 0.0 / 0.0;        TASSERT (!(d == d) && std::isnan (d));
  // check rounding
  TASSERT (int (+0.40) == +0.0 && Bse::irintf (+0.40) == +0.0);
  TASSERT (int (-0.40) == -0.0 && Bse::irintf (-0.40) == -0.0);
  TASSERT (int (+0.51) == +0.0 && Bse::irintf (+0.51) == +1.0);
  TASSERT (int (-0.51) == -0.0 && Bse::irintf (-0.51) == -1.0);
  TASSERT (int (+1.90) == +1.0 && Bse::irintf (+1.90) == +2.0);
  TASSERT (int (-1.90) == -1.0 && Bse::irintf (-1.90) == -2.0);
  // check fast_exp2(int), 2^(-126..+127) must be calculated with 0 error
  volatile float m = 1.0, p = 1.0;
  for (ssize_t i = 0; i <= 127; i++)
    {
      // Bse::printerr ("2^±%-3d = %15.10g, %-.14g\n", i, fast_exp2 (i), fast_exp2 (-i));
      TASSERT (fast_exp2 (i) == p);
      if (i != 127)
        TASSERT (fast_exp2 (-i) == m);
      else
        TASSERT (fast_exp2 (-i) <= m); // single precision result for 2^-127 is 0 or subnormal
      p *= 2;
      m /= 2;
    }
  // check fast_exp2 error margin in [-1..+1]
  const double step = Bse::Test::slow() ? 0.0000001 : 0.0001;
  for (double d = -1; d <= +1; d += step)
    {
      const double r = std::exp2 (d);
      const double err = std::fabs (r - fast_exp2 (d));
      TASSERT (err < 4e-7);
    }
}
TEST_ADD (fast_math_test);

template<typename V, typename F, typename G> static long double
range_error (V vmin, V vmax, V vstep, F f, G g, V *errpos)
{
  long double err = 0;
  for (V input = vmin; input < vmax; input += vstep)
    {
      const long double vf = f (input), vg = g (input);
      const auto old = err;
      err = std::max (err, vf < vg ? vg - vf : vf - vg);
      // err = std::max (err, vf < vg ? (vg - vf) / vf : (vf - vg) / vg);
      if (old != err)
        *errpos = input;
    }
  return err;
}

static const float START_RANGE = -90, END_RANGE = 90;
static const float RANGE_STEP = 0.001;
static const float ERROR_START = -1, ERROR_END = +1, ERROR_STEP = 0.0000001;
static float frange_accu;

template<typename Lambda> static void
frange_print_bench (Lambda lambda, const String &name, double bench_time)
{
  const double N_STEPS = (END_RANGE - START_RANGE) / RANGE_STEP;
  float pos = 0;
  double rerr = range_error<float> (ERROR_START, ERROR_END, ERROR_STEP, exp2, lambda, &pos);
  TBENCH ("%-18s # timing: fastest=%fs calls=%.1f/s diff=%.20f (@%f)\n",
          name, bench_time, N_STEPS / bench_time, rerr, pos);
  TASSERT (frange_accu != 0);
  TASSERT (!std::isnan (frange_accu));
}
#define FRANGE_BENCH(FUN) ({                    \
  frange_accu = 0;                                   \
  double t = timer.benchmark ([] () {                                              \
                                for (float n = START_RANGE; n <= END_RANGE; n += RANGE_STEP) \
                                  frange_accu += FUN (n); \
                              });                                       \
  t; })

static void
fast_math_bench()
{
  Test::Timer timer (0.15); // maximum seconds
  frange_print_bench (exp2f, "exp2f", FRANGE_BENCH (exp2f));
  frange_print_bench (fast_exp2, "fast_exp2", FRANGE_BENCH (fast_exp2));
  frange_print_bench (bse_approx5_exp2, "bse_approx5_exp2", FRANGE_BENCH (bse_approx5_exp2));
  frange_print_bench (bse_approx6_exp2, "bse_approx6_exp2", FRANGE_BENCH (bse_approx6_exp2));
  frange_print_bench (bse_approx7_exp2, "bse_approx7_exp2", FRANGE_BENCH (bse_approx7_exp2));
}
TEST_BENCH (fast_math_bench);

#if 0
int
main (gint   argc,
      gchar *argv[])
{
  bse_init_test (&argc, argv);
  test_math_bits();
  check_cent_tune();
  check_cent_tune_fast();
  check_equal_tempered_tuning();
  check_monotonic_tuning();
  return 0;
}
#endif
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#include <dune/stuff/test/test_common.hh>

#include <memory>

#include <dune/common/exceptions.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/functions/combined.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/la/container/eigen.hh>

#include <dune/gdt/space/continuouslagrange/fem.hh>
#include <dune/gdt/space/continuouslagrange/fem-localfunctions.hh>
#include <dune/gdt/space/discontinuouslagrange/fem-localfunctions.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/operator/projections.hh>
#include <dune/gdt/operator/products.hh>

class errors_are_not_as_expected
  : public Dune::Exception
{};

typedef Dune::Stuff::GridProviderCube< Dune::GridSelector::GridType > GridProviderType;
typedef typename GridProviderType::GridType                           GridType;
typedef Dune::grid::Part::Leaf::Const< GridType >                     GridPartType;
typedef typename GridPartType::template Codim< 0 >::EntityType        EntityType;
typedef typename GridPartType::IntersectionType                       IntersectionType;
typedef Dune::Stuff::GridboundaryAllDirichlet< IntersectionType >     BoundaryInfoType;
typedef typename GridPartType::ctype  DomainFieldType;
static const unsigned int             dimDomain = GridPartType::dimension;
typedef double                        RangeFieldType;
static const unsigned int             dimRange = 1;
typedef Dune::Stuff::Function::Expression
    < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > FunctionType;
typedef Dune::Stuff::LA::EigenDenseVector< RangeFieldType > VectorType;

typedef testing::Types< Dune::GDT::ContinuousLagrangeSpace::FemWrapper< GridPartType, 1, RangeFieldType, dimRange >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< GridPartType, 2, RangeFieldType, dimRange >
                      , Dune::GDT::ContinuousLagrangeSpace::FemLocalfunctionsWrapper< GridPartType, 1, RangeFieldType, dimRange >
                      , Dune::GDT::ContinuousLagrangeSpace::FemLocalfunctionsWrapper< GridPartType, 2, RangeFieldType, dimRange >
                      , Dune::GDT::DiscontinuousLagrangeSpace::FemLocalfunctionsWrapper< GridPartType, 1, RangeFieldType, dimRange >
                      , Dune::GDT::DiscontinuousLagrangeSpace::FemLocalfunctionsWrapper< GridPartType, 2, RangeFieldType, dimRange >
                      > SpaceTypes;

template< class SpaceType >
struct L2ProjectionOperator
  : public ::testing::Test
{
  void check() const
  {
    // prepare
    GridProviderType grid_provider;
    auto grid = grid_provider.grid();
    grid->globalRefine(4);
    const auto grid_part = std::make_shared< const GridPartType >(*grid);
    const SpaceType space(grid_part);
    const FunctionType function("x", "x[0]", 1, "function");
    VectorType vector(space.mapper().size());
    typedef Dune::GDT::DiscreteFunction< SpaceType, VectorType > DiscreteFunctionType;
    DiscreteFunctionType discrete_function(space, vector, "discrete function");
    // project
    const Dune::GDT::ProjectionOperator::L2< GridPartType > l2_projection_operator(*grid_part);
    l2_projection_operator.apply(function, discrete_function);
    // measure error
    const Dune::Stuff::Function::Difference< FunctionType, DiscreteFunctionType > difference(function,
                                                                                discrete_function);
    const Dune::GDT::ProductOperator::L2< GridPartType > l2_product_operator(*grid_part);
    const auto l2_error = std::sqrt(l2_product_operator.apply2(difference, difference));
    if (l2_error > 1e-14)
      DUNE_THROW(errors_are_not_as_expected, "They really ain't!");
  }
};

TYPED_TEST_CASE(L2ProjectionOperator, SpaceTypes);
TYPED_TEST(L2ProjectionOperator, compiles) {
  this->check();
}

int main(int argc, char** argv)
{
  try {
    test_init(argc, argv);
    return RUN_ALL_TESTS();
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
    std::abort();
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
    std::abort();
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
    std::abort();
  } // try
}
<commit_msg>[tests.operators] rewrite * use the proper grids, independent of GRIDTYPE and GRIDDIM * finished test of {L2,H1Semi}ProductOperator (all works)<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

// disable all grids before we include config.h
#ifdef GRIDDIM
# undef GRIDDIM
#endif
#ifdef YASPGRID
# undef YASPGRID
#endif
#ifdef ALBERTAGRID
# undef ALBERTAGRID
#endif
#ifdef UGGRID
# undef UGGRID
#endif
#ifdef ALUGRID_CONFORM
# undef ALUGRID_CONFORM
#endif
#ifdef ALUGRID_CUBE
# undef ALUGRID_CUBE
#endif
#ifdef ALUGRID_SIMPLEX
# undef ALUGRID_SIMPLEX
#endif
#ifdef ONEDGRID
# undef ONEDGRID
#endif
#ifdef SGRID
# undef SGRID
#endif

#include <dune/stuff/test/test_common.hh>

# include <memory>

# include <dune/common/exceptions.hh>
# include <dune/common/float_cmp.hh>

#if HAVE_ALUGRID_SERIAL_H || HAVE_ALUGRID_PARALLEL_H
// enable alugrid
# define GRIDDIM 2
# define ENABLE_ALUGRID 1
# include <dune/grid/alugrid.hh>
#endif
#include <dune/grid/sgrid.hh>
#include <dune/grid/yaspgrid.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/la/container/eigen.hh>

#include <dune/gdt/space/continuouslagrange/fem.hh>
#include <dune/gdt/space/continuouslagrange/fem-localfunctions.hh>
#include <dune/gdt/space/discontinuouslagrange/fem-localfunctions.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/operator/projections.hh>
#include <dune/gdt/operator/products.hh>

class errors_are_not_as_expected
  : public Dune::Exception
{};

typedef Dune::Stuff::LA::EigenDenseVector< double > VectorType;

typedef Dune::SGrid< 1, 1 >                           S1dGridType;
typedef Dune::grid::Part::Leaf::Const< S1dGridType >  S1dGridPartType;
typedef Dune::SGrid< 2, 2 >                           S2dGridType;
typedef Dune::grid::Part::Leaf::Const< S2dGridType >  S2dGridPartType;
typedef Dune::SGrid< 3, 3 >                           S3dGridType;
typedef Dune::grid::Part::Leaf::Const< S3dGridType >  S3dGridPartType;

typedef Dune::YaspGrid< 1 >                             Yasp1dGridType;
typedef Dune::grid::Part::Leaf::Const< Yasp1dGridType > Yasp1dGridPartType;
typedef Dune::YaspGrid< 2 >                             Yasp2dGridType;
typedef Dune::grid::Part::Leaf::Const< Yasp2dGridType > Yasp2dGridPartType;
typedef Dune::YaspGrid< 3 >                             Yasp3dGridType;
typedef Dune::grid::Part::Leaf::Const< Yasp3dGridType > Yasp3dGridPartType;

typedef Dune::ALUConformGrid< 2, 2 >                                  AluConform2dGridType;
typedef Dune::grid::Part::Leaf::Const< AluConform2dGridType >         AluConform2dGridPartType;

typedef testing::Types< Dune::GDT::ContinuousLagrangeSpace::FemWrapper< S1dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< S1dGridPartType, 2, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< S2dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< S2dGridPartType, 2, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< S3dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< S3dGridPartType, 2, double, 1 >

                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< Yasp1dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< Yasp1dGridPartType, 2, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< Yasp2dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< Yasp2dGridPartType, 2, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< Yasp3dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< Yasp3dGridPartType, 2, double, 1 >
#if HAVE_ALUGRID
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< AluConform2dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemWrapper< AluConform2dGridPartType, 2, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemLocalfunctionsWrapper< AluConform2dGridPartType, 1, double, 1 >
                      , Dune::GDT::ContinuousLagrangeSpace::FemLocalfunctionsWrapper< AluConform2dGridPartType, 2, double, 1 >
                      , Dune::GDT::DiscontinuousLagrangeSpace::FemLocalfunctionsWrapper< AluConform2dGridPartType, 1, double, 1 >
                      , Dune::GDT::DiscontinuousLagrangeSpace::FemLocalfunctionsWrapper< AluConform2dGridPartType, 2, double, 1 >
#endif
                      > L2ProductOperatorSpaceTypes;

template< class SpaceType >
struct L2ProductOperator
  : public ::testing::Test
{
  typedef typename SpaceType::GridPartType          GridPartType;
  typedef typename GridPartType::GridType           GridType;
  typedef Dune::Stuff::GridProviderCube< GridType > GridProviderType;
  typedef typename GridPartType::template Codim< 0 >::EntityType EntityType;
  typedef typename SpaceType::DomainFieldType DomainFieldType;
  static const unsigned int                   dimDomain = SpaceType::dimDomain;
  typedef typename SpaceType::RangeFieldType  RangeFieldType;
  static const unsigned int                   dimRange = SpaceType::dimRange;
  typedef Dune::Stuff::Function::Expression
      < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > FunctionType;

  void check() const
  {
    // prepare
    const GridProviderType grid_provider(0.0, 1.0, 4u);
    const auto grid = grid_provider.grid();
    const auto grid_part = std::make_shared< const GridPartType >(*grid);
    const Dune::GDT::ProductOperator::L2< GridPartType > l2_product_operator(*grid_part);
    // test 1 (constant)
    const FunctionType function_1("x", "1.0", 0);
    auto l2_product = l2_product_operator.apply2(function_1, function_1);
    if (Dune::FloatCmp::ne(l2_product, RangeFieldType(1)))
      DUNE_THROW(errors_are_not_as_expected, "They really ain't!");
    // test 2 (linear)
    const FunctionType function_2("x", "x[0] - 1.0", 1);
    l2_product = l2_product_operator.apply2(function_2, function_2);
    if (Dune::FloatCmp::ne(l2_product, RangeFieldType(1.0/3.0)))
      DUNE_THROW(errors_are_not_as_expected, "They really ain't!");
    // test 3 (quadratic)
    const FunctionType function_3("x", "x[0]*x[0]", 2);
    l2_product = l2_product_operator.apply2(function_3, function_3);
    if (Dune::FloatCmp::ne(l2_product, RangeFieldType(1.0/5.0)))
      DUNE_THROW(errors_are_not_as_expected, "They really ain't!");
  }
};

TYPED_TEST_CASE(L2ProductOperator, L2ProductOperatorSpaceTypes);
TYPED_TEST(L2ProductOperator, produces_correct_results) {
  this->check();
}

template< class SpaceType >
struct H1SemiProductOperator
  : public ::testing::Test
{
  typedef typename SpaceType::GridPartType          GridPartType;
  typedef typename GridPartType::GridType           GridType;
  typedef Dune::Stuff::GridProviderCube< GridType > GridProviderType;
  typedef typename GridPartType::template Codim< 0 >::EntityType EntityType;
  typedef typename SpaceType::DomainFieldType DomainFieldType;
  static const unsigned int                   dimDomain = SpaceType::dimDomain;
  typedef typename SpaceType::RangeFieldType  RangeFieldType;
  static const unsigned int                   dimRange = SpaceType::dimRange;
  typedef Dune::Stuff::Function::Expression
      < EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > FunctionType;

  void check() const
  {
    // prepare
    const GridProviderType grid_provider(0.0, 1.0, 4u);
    const auto grid = grid_provider.grid();
    const auto grid_part = std::make_shared< const GridPartType >(*grid);
    const Dune::GDT::ProductOperator::H1Semi< GridPartType > h1semi_product_operator(*grid_part);
    // test 1 (constant)
    const FunctionType function_1("x", "fake_value", 1, "constant gradient", {{"1.0", "1.0", "1.0"}});
    auto h1semi_product = h1semi_product_operator.apply2(function_1, function_1);
    if (Dune::FloatCmp::ne(h1semi_product, dimDomain * RangeFieldType(1.0)))
      DUNE_THROW(errors_are_not_as_expected, "They really ain't!");
    // test 2 (linear)
    const FunctionType function_2("x", "fake_value", 2, "affine gradient",
                                  {{"x[0] - 1.0", "x[0] - 1.0", "x[0] - 1.0"}});
    h1semi_product = h1semi_product_operator.apply2(function_2, function_2);
    if (Dune::FloatCmp::ne(h1semi_product, dimDomain * RangeFieldType(1.0/3.0)))
      DUNE_THROW(errors_are_not_as_expected, "They really ain't!");
    // test 3 (quadratic)
    const FunctionType function_3("x", "fake_value", 3, ", quadratic gradient",
                                  {{"x[0]*x[0]", "x[0]*x[0]", "x[0]*x[0]"}});
    h1semi_product = h1semi_product_operator.apply2(function_3, function_3);
    if (Dune::FloatCmp::ne(h1semi_product, dimDomain * RangeFieldType(1.0/5.0)))
      DUNE_THROW(errors_are_not_as_expected, "They really ain't!");
  }
};

TYPED_TEST_CASE(H1SemiProductOperator, L2ProductOperatorSpaceTypes);
TYPED_TEST(H1SemiProductOperator, produces_correct_results) {
  this->check();
}

int main(int argc, char** argv)
{
  try {
    test_init(argc, argv);
    return RUN_ALL_TESTS();
  } catch (Dune::Exception& e) {
    std::cerr << "Dune reported error: " << e.what() << std::endl;
    std::abort();
  } catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
    std::abort();
  } catch (...) {
    std::cerr << "Unknown exception thrown!" << std::endl;
    std::abort();
  } // try
}
<|endoftext|>


<commit_before>/**
 * Copyright Soramitsu Co., Ltd. 2016 All Rights Reserved.
 * http://soramitsu.co.jp
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ametsuchi/cache.h>
#include <benchmark/benchmark.h>
#include <stdint.h>
#include <algorithm>

/**
 * Generates a list of `len` random numbers in range [start; end]
 * @param start - min item in sequence
 * @param end - max item in sequence
 * @param len - length of a sequence
 * @return returns std::list of random integers
 */
std::list<uint32_t> generateAccessSequence(uint32_t start, uint32_t end,
                                           uint32_t len) {
  unsigned int seed = 0;
  std::list<uint32_t> ret;
  for (uint32_t i = 0; i < len; i++) {
    uint32_t r = (rand_r(&seed) % (end - start)) + start;
    ret.push_back(r);
  }
  return ret;
}

static void Cache_RandomAccess(benchmark::State& state) {
  // unit of storage
  struct Page {
    char buf[4096];
  };

  auto sequence = generateAccessSequence(0, state.range(0), state.range(1));
  auto begin = sequence.begin();
  auto end = sequence.end();
  ametsuchi::Cache<int, Page> cache(state.range(2));
  uint64_t items = 0;
  while (state.KeepRunning()) {
    // simulate cache
    auto item = cache.get(*begin);
    if (item == nullptr) {
      cache.put(*begin, std::move(Page()));
    }

    state.PauseTiming();
    if (begin == end)
      begin = sequence.begin();
    else
      ++begin;

    items++;
    state.ResumeTiming();
  }

  state.SetBytesProcessed(sizeof(Page) * static_cast<uint64_t>(state.range(1)) *
                          static_cast<uint64_t>(state.iterations()));

  state.SetItemsProcessed(items);
}

/**
 * We generate a sequence of "accesses" to pages (just numbers).
 * It is from 1 << 8 to 1 << 15 (state.range(0))
 * Length of this sequence is from 1 << 15 to 1 << 16 (stage.range(1))
 * {256, 256} - is cache size (items)
 */
BENCHMARK(Cache_RandomAccess)
    ->RangeMultiplier(2)
    ->Ranges({{1 << 8, 1 << 15}, {1 << 15, 1 << 16}, {256, 256}})
    ->Complexity(benchmark::oAuto);

BENCHMARK_MAIN();
<commit_msg>Fixed cache benchamark (#13)<commit_after>/**
 * Copyright Soramitsu Co., Ltd. 2016 All Rights Reserved.
 * http://soramitsu.co.jp
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ametsuchi/cache.h>
#include <benchmark/benchmark.h>
#include <stdint.h>
#include <algorithm>

/**
 * Generates a list of `len` random numbers in range [start; end]
 * @param start - min item in sequence
 * @param end - max item in sequence
 * @param len - length of a sequence
 * @return returns std::list of random integers
 */
std::list<uint32_t> generateAccessSequence(uint32_t start, uint32_t end,
                                           uint32_t len) {
  unsigned int seed = 0;
  std::list<uint32_t> ret;
  for (uint32_t i = 0; i < len; i++) {
    uint32_t r = (rand_r(&seed) % (end - start)) + start;
    ret.push_back(r);
  }
  return ret;
}

static void Cache_RandomAccess(benchmark::State& state) {
  // unit of storage
  struct Page {
    char buf[4096];
  };

  auto sequence = generateAccessSequence(0, state.range(0), state.range(1));
  auto begin = sequence.begin();
  auto end = sequence.end();
  ametsuchi::Cache<int, Page> cache(state.range(2));
  uint64_t items = 0;
  while (state.KeepRunning()) {
    // simulate cache
    auto item = cache.get(*begin);
    if (item == nullptr) {
      cache.put(*begin, Page());
    }

    state.PauseTiming();
    if (begin == end)
      begin = sequence.begin();
    else
      ++begin;

    items++;
    state.ResumeTiming();
  }

  state.SetBytesProcessed(sizeof(Page) * static_cast<uint64_t>(state.range(1)) *
                          static_cast<uint64_t>(state.iterations()));

  state.SetComplexityN(state.range(1));
  state.SetItemsProcessed(items);
}

/**
 * We generate a sequence of "accesses" to pages (just numbers).
 * It is from 1 << 8 to 1 << 15 (state.range(0))
 * Length of this sequence is from 1 << 15 to 1 << 16 (stage.range(1))
 * {256, 256} - is cache size (items)
 */
BENCHMARK(Cache_RandomAccess)
    ->RangeMultiplier(2)
    ->Ranges({{1 << 8, 1 << 15}, {1 << 15, 1 << 16}, {256, 256}})
    ->Complexity(benchmark::oAuto);

BENCHMARK_MAIN();
<|endoftext|>


<commit_before><commit_msg>Fix affinity printing<commit_after><|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) FFLAS-FFPACK
 * Written by Pascal Giorgi <pascal.giorgi@lirmm.fr>
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

#include <givaro/modular-integer.h>

#include <iomanip>
#include <iostream>

#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "test-utils.h"
#include <givaro/modular.h>
#include <givaro/unparametric.h>
#include <givaro/modular-balanced.h>

using namespace std;
using namespace FFPACK;
using Givaro::UnparametricRing;;
using Givaro::Modular;
using Givaro::ModularBalanced;

template<typename T>
void write_matrix(Givaro::Integer p, size_t m, size_t n, T* C, size_t ldc){

	size_t www=(p.bitsize()*log(2.))/log(10.);
	for (size_t i=0;i<m;++i){
		cout<<"[ ";
		cout.width(www+1);
		cout<<std::right<<C[i*ldc];
		for (size_t j=1;j<n;++j){
			cout<<" ";
			cout.width(www);
			cout<<std::right<<C[i*ldc+j];
		}
		cout<<"]"<<endl;
	}
	cout<<endl;

}

template<typename Field>
bool check_ftrsm (const Field &F, size_t m, size_t n, const typename Field::Element &alpha, FFLAS::FFLAS_SIDE side, FFLAS::FFLAS_UPLO uplo, FFLAS::FFLAS_TRANSPOSE trans, FFLAS::FFLAS_DIAG diag){

	typedef typename Field::Element Element;
	Element * A, *B, *B2, *C, tmp;
	size_t k = (side==FFLAS::FflasLeft?m:n);
	size_t lda,ldb,ldc;
	lda=k+13;
	ldb=n+14;
	ldc=n+15;
	A  = FFLAS::fflas_new(F,k,lda);
	B  = FFLAS::fflas_new(F,m,ldb);
	B2 = FFLAS::fflas_new(F,m,ldb);
	C  = FFLAS::fflas_new(F,m,ldc);

	typename Field::RandIter Rand(F);

	for (size_t i=0;i<k;++i){
		for (size_t j=0;j<i;++j)
			A[i*lda+j]= (uplo == FFLAS::FflasLower)? Rand.random(tmp) : F.zero;
		A[i*lda+i]= (diag == FFLAS::FflasNonUnit)? Rand.random(tmp) : F.one;
		for (size_t j=i+1;j<k;++j)
			A[i*lda+j]= (uplo == FFLAS::FflasUpper)? Rand.random(tmp) : F.zero;
	}
	for (size_t i=0;i<m;++i){
		for(size_t j=0; j<n; ++j){
			B[i*ldb+j]= Rand.random(tmp);
			B2[i*ldb+j]=B[i*ldb+j];
		}
	}

	string ss=string((uplo == FFLAS::FflasLower)?"Lower_":"Upper_")+string((side == FFLAS::FflasLeft)?"Left_":"Right_")+string((trans == FFLAS::FflasTrans)?"Trans_":"NoTrans_")+string((diag == FFLAS::FflasUnit)?"Unit":"NonUnit");

	cerr<<std::left<<"Checking FTRSM_";
	cerr.fill('.');
	cerr.width(35);
	cerr<<ss;

	FFLAS::Timer t; t.clear();
	double time=0.0;
	t.clear();
	t.start();
	FFLAS::ftrsm (F, side, uplo, trans, diag, m, n, alpha, A, lda, B, ldb);
	t.stop();
	time+=t.usertime();

	Element invalpha;
	F.init(invalpha);
	F.inv(invalpha, alpha);

	//FFLAS::ftrmm (F, side, uplo, trans, diag, m, n, invalpha, A, k, B, n);

	if (side == FFLAS::FflasLeft)
		FFLAS::fgemm(F, trans, FFLAS::FflasNoTrans, m, n, m, invalpha, A, lda, B, ldb, F.zero, C, ldc);
	else
		FFLAS::fgemm(F, FFLAS::FflasNoTrans, trans, m, n, n, invalpha, B, ldb, A, lda, F.zero, C, ldc);

	bool wrong = false;
	for (size_t i=0;i<m;++i)
		for (size_t j=0;j<n;++j)
			if ( !F.areEqual(*(B2+i*ldb+j), *(C+i*ldc+j))){
				wrong = true;
			}
	if ( wrong ){
		cerr << "\033[1;31mFAILED\033[0m ("<<time<<")"<<endl;
		//cerr<<"FAILED ("<<time<<")"<<endl;

	} else
		cerr << "\033[1;32mPASSED\033[0m ("<<time<<")"<<endl;
	//cerr<<"PASSED ("<<time<<")"<<endl;

	F.mulin(invalpha,alpha);
	if (!F.isOne(invalpha)){
		cerr<<"invalpha is wrong !!!"<<endl;;
	}

	FFLAS::fflas_delete(A);
	FFLAS::fflas_delete(B);
	FFLAS::fflas_delete(B2);
	FFLAS::fflas_delete(C);
	return !wrong;
}
template <class Field>
bool run_with_field (Givaro::Integer q, unsigned long b, size_t m, size_t n, int s, size_t iters){
	bool ok = true ;
	int nbit=(int)iters;

	while (ok &&  nbit){
		//typedef typename Field::Element Element ;
		// choose Field
		Field* F= chooseField<Field>(q,b);
		if (F==nullptr)
			return true;

		typename Field::Element alpha;
		F->init (alpha, (typename Field::Element)s);
		cerr<<"Checking with ";F->write(cerr)<<endl;

		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		nbit--;
		delete F;
	}
	return ok;
}

int main(int argc, char** argv)
{
	cerr<<setprecision(10);
	static Givaro::Integer q=-1;
	static size_t b=0;
	static size_t m=128;
	static size_t n=128;
	static size_t s=1;
	static size_t iters=1;
	static bool loop=false;
	static Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INTEGER , &q },
                { 'b', "-b B", "Set the bitsize of the field characteristic.",  TYPE_INT , &b },
                { 'm', "-m M", "Set the row dimension of unknown matrix.",      TYPE_INT , &m },
                { 'n', "-n N", "Set the column dimension of the unknown matrix.", TYPE_INT , &n },
                { 's', "-s S", "Set the scaling of trsm",                         TYPE_INT , &s },
		{ 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iters },
		{ 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
                END_OF_ARGUMENTS
        };

	FFLAS::parseArguments(argc,argv,as);

	bool ok = true;
	do{
	 	ok &= run_with_field<Modular<double> >(q,b,m,n,s,iters);
		ok &= run_with_field<ModularBalanced<double> >(q,b,m,n,s,iters);
		ok &= run_with_field<Modular<float> >(q,b,m,n,s,iters);
		ok &= run_with_field<ModularBalanced<float> >(q,b,m,n,s,iters);
		ok &= run_with_field<Modular<int32_t> >(q,b,m,n,s,iters);
		ok &= run_with_field<ModularBalanced<int32_t> >(q,b,m,n,s,iters);
		ok &= run_with_field<Modular<Givaro::Integer> >(q,(b?b:512),m,n,s,iters); // BUG: random entry are not of the chosen bitsize (RandIter are wrong)
	} while (loop && ok);

	return !ok ;
}
<commit_msg>fix bug in test<commit_after>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/*
 * Copyright (C) FFLAS-FFPACK
 * Written by Pascal Giorgi <pascal.giorgi@lirmm.fr>
 * This file is Free Software and part of FFLAS-FFPACK.
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 *.
 */

#include <givaro/modular-integer.h>

#include <iomanip>
#include <iostream>

#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "test-utils.h"
#include <givaro/modular.h>
#include <givaro/unparametric.h>
#include <givaro/modular-balanced.h>

using namespace std;
using namespace FFPACK;
using Givaro::UnparametricRing;;
using Givaro::Modular;
using Givaro::ModularBalanced;

template<typename T>
void write_matrix(Givaro::Integer p, size_t m, size_t n, T* C, size_t ldc){

	size_t www=(p.bitsize()*log(2.))/log(10.);
	for (size_t i=0;i<m;++i){
		cout<<"[ ";
		cout.width(www+1);
		cout<<std::right<<C[i*ldc];
		for (size_t j=1;j<n;++j){
			cout<<" ";
			cout.width(www);
			cout<<std::right<<C[i*ldc+j];
		}
		cout<<"]"<<endl;
	}
	cout<<endl;

}

template<typename Field>
bool check_ftrsm (const Field &F, size_t m, size_t n, const typename Field::Element &alpha, FFLAS::FFLAS_SIDE side, FFLAS::FFLAS_UPLO uplo, FFLAS::FFLAS_TRANSPOSE trans, FFLAS::FFLAS_DIAG diag){

	typedef typename Field::Element Element;
	Element * A, *B, *B2, *C, tmp;
	size_t k = (side==FFLAS::FflasLeft?m:n);
	size_t lda,ldb,ldc;
	lda=k+13;
	ldb=n+14;
	ldc=n+15;
	A  = FFLAS::fflas_new(F,k,lda);
	B  = FFLAS::fflas_new(F,m,ldb);
	B2 = FFLAS::fflas_new(F,m,ldb);
	C  = FFLAS::fflas_new(F,m,ldc);

	typename Field::RandIter Rand(F);
	typename Field::NonZeroRandIter NZRand(F,Rand);

	for (size_t i=0;i<k;++i){
		for (size_t j=0;j<i;++j)
			A[i*lda+j]= (uplo == FFLAS::FflasLower)? Rand.random(tmp) : F.zero;
		A[i*lda+i]= (diag == FFLAS::FflasNonUnit)? NZRand.random(tmp) : F.one;
		for (size_t j=i+1;j<k;++j)
			A[i*lda+j]= (uplo == FFLAS::FflasUpper)? Rand.random(tmp) : F.zero;
	}
	for (size_t i=0;i<m;++i){
		for(size_t j=0; j<n; ++j){
			B[i*ldb+j]= Rand.random(tmp);
			B2[i*ldb+j]=B[i*ldb+j];
		}
	}

	string ss=string((uplo == FFLAS::FflasLower)?"Lower_":"Upper_")+string((side == FFLAS::FflasLeft)?"Left_":"Right_")+string((trans == FFLAS::FflasTrans)?"Trans_":"NoTrans_")+string((diag == FFLAS::FflasUnit)?"Unit":"NonUnit");

	cerr<<std::left<<"Checking FTRSM_";
	cerr.fill('.');
	cerr.width(35);
	cerr<<ss;

	FFLAS::Timer t; t.clear();
	double time=0.0;
	t.clear();
	t.start();
	FFLAS::ftrsm (F, side, uplo, trans, diag, m, n, alpha, A, lda, B, ldb);
	t.stop();
	time+=t.usertime();

	Element invalpha;
	F.init(invalpha);
	F.inv(invalpha, alpha);

	//FFLAS::ftrmm (F, side, uplo, trans, diag, m, n, invalpha, A, k, B, n);

	if (side == FFLAS::FflasLeft)
		FFLAS::fgemm(F, trans, FFLAS::FflasNoTrans, m, n, m, invalpha, A, lda, B, ldb, F.zero, C, ldc);
	else
		FFLAS::fgemm(F, FFLAS::FflasNoTrans, trans, m, n, n, invalpha, B, ldb, A, lda, F.zero, C, ldc);

	bool wrong = false;
	for (size_t i=0;i<m;++i)
		for (size_t j=0;j<n;++j)
			if ( !F.areEqual(*(B2+i*ldb+j), *(C+i*ldc+j))){
				wrong = true;
			}
	if ( wrong ){
		cerr << "\033[1;31mFAILED\033[0m ("<<time<<")"<<endl;
		//cerr<<"FAILED ("<<time<<")"<<endl;

	} else
		cerr << "\033[1;32mPASSED\033[0m ("<<time<<")"<<endl;
	//cerr<<"PASSED ("<<time<<")"<<endl;

	F.mulin(invalpha,alpha);
	if (!F.isOne(invalpha)){
		cerr<<"invalpha is wrong !!!"<<endl;;
	}

	FFLAS::fflas_delete(A);
	FFLAS::fflas_delete(B);
	FFLAS::fflas_delete(B2);
	FFLAS::fflas_delete(C);
	return !wrong;
}
template <class Field>
bool run_with_field (Givaro::Integer q, unsigned long b, size_t m, size_t n, int s, size_t iters){
	bool ok = true ;
	int nbit=(int)iters;

	while (ok &&  nbit){
		//typedef typename Field::Element Element ;
		// choose Field
		Field* F= chooseField<Field>(q,b);
		if (F==nullptr)
			return true;

		typename Field::Element alpha;
		F->init (alpha, (typename Field::Element)s);
		cerr<<"Checking with ";F->write(cerr)<<endl;

		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasLeft,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasNoTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasLower,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		ok = ok && check_ftrsm(*F,m,n,alpha,FFLAS::FflasRight,FFLAS::FflasUpper,FFLAS::FflasTrans,FFLAS::FflasNonUnit);
		nbit--;
		delete F;
	}
	return ok;
}

int main(int argc, char** argv)
{
	cerr<<setprecision(10);
	static Givaro::Integer q=-1;
	static size_t b=0;
	static size_t m=128;
	static size_t n=128;
	static size_t s=1;
	static size_t iters=1;
	static bool loop=false;
	static Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INTEGER , &q },
                { 'b', "-b B", "Set the bitsize of the field characteristic.",  TYPE_INT , &b },
                { 'm', "-m M", "Set the row dimension of unknown matrix.",      TYPE_INT , &m },
                { 'n', "-n N", "Set the column dimension of the unknown matrix.", TYPE_INT , &n },
                { 's', "-s S", "Set the scaling of trsm",                         TYPE_INT , &s },
		{ 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iters },
		{ 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
                END_OF_ARGUMENTS
        };

	FFLAS::parseArguments(argc,argv,as);

	bool ok = true;
	do{
	 	ok &= run_with_field<Modular<double> >(q,b,m,n,s,iters);
		ok &= run_with_field<ModularBalanced<double> >(q,b,m,n,s,iters);
		ok &= run_with_field<Modular<float> >(q,b,m,n,s,iters);
		ok &= run_with_field<ModularBalanced<float> >(q,b,m,n,s,iters);
		ok &= run_with_field<Modular<int32_t> >(q,b,m,n,s,iters);
		ok &= run_with_field<ModularBalanced<int32_t> >(q,b,m,n,s,iters);
		ok &= run_with_field<Modular<Givaro::Integer> >(q,(b?b:512),m,n,s,iters); // BUG: random entry are not of the chosen bitsize (RandIter are wrong)
	} while (loop && ok);

	return !ok ;
}
<|endoftext|>


<commit_before>#include "utest.h"
#define CATCH_CONFIG_RUNNER
#include "../../include/catch.hpp"

UTest::UTest()
{

}

TEST_CASE( "Creating message", "[message]" )
{
    mbedtls_entropy_context mtls_entropy;
    mbedtls_entropy_init(&mtls_entropy);
    mbedtls_entropy_gather(&mtls_entropy);

    Session s("keket", "druhykeket", &mtls_entropy);

    Session s2("druhykeket", "keket", &mtls_entropy);

    s.getKey().setDH(s2.getKey().getDH());
    s2.getKey().setDH(s.getKey().getDH());
	s.getKey().generateKey();
	s2.getKey().generateKey();

	bool same = s.getKey().getSharedKey() == s2.getKey().getSharedKey();
	REQUIRE(same);

    Messages m(nullptr, 0);
    QString sprava("TESTOVACIA SPRAVA");

    QByteArray encrypted = m.createRegularMessage(s, sprava);

	qDebug() << "PROTECTED:   " << encrypted;

    Messages::ReceivedMessage received;
    bool valid = m.parseMessage(s2, encrypted, received);

	REQUIRE(valid);

	QString receivedString;
	receivedString.fromUtf8(received.messageText);

	qDebug() << "UNPROTECTED: " << receivedString;

    REQUIRE(receivedString == sprava);

}

int UTest::makeTests(int argc, char *argv[])
{
    return Catch::Session().run( 1, argv );

//    mbedtls_entropy_context mtls_entropy;

//    Session mSession("keket", "dalsikeket", &mtls_entropy);

//    Messages messages(nullptr, 0);

//    QString daco = messages.createRegularMessage(mSession, "KOKOTINA");

//    qDebug() << daco;

}
<commit_msg>Unit test fixed conversion from utf8<commit_after>#include "utest.h"
#define CATCH_CONFIG_RUNNER
#include "../../include/catch.hpp"

UTest::UTest()
{

}

TEST_CASE( "Creating message", "[message]" )
{
    mbedtls_entropy_context mtls_entropy;
    mbedtls_entropy_init(&mtls_entropy);
    mbedtls_entropy_gather(&mtls_entropy);

    Session s("keket", "druhykeket", &mtls_entropy);

    Session s2("druhykeket", "keket", &mtls_entropy);

    s.getKey().setDH(s2.getKey().getDH());
    s2.getKey().setDH(s.getKey().getDH());
	s.getKey().generateKey();
	s2.getKey().generateKey();

	bool same = s.getKey().getSharedKey() == s2.getKey().getSharedKey();
	REQUIRE(same);

    Messages m(nullptr, 0);
    QString sprava("TESTOVACIA SPRAVA");

    QByteArray encrypted = m.createRegularMessage(s, sprava);

	qDebug() << "PROTECTED:   " << encrypted;

    Messages::ReceivedMessage received;
    bool valid = m.parseMessage(s2, encrypted, received);

	REQUIRE(valid);

	qDebug() << "Raw unprotected = " << received.messageText;

	QString receivedString = QString::fromUtf8(received.messageText);

	qDebug() << "UNPROTECTED: " << receivedString;

    REQUIRE(receivedString == sprava);

}

int UTest::makeTests(int argc, char *argv[])
{
    return Catch::Session().run( 1, argv );

//    mbedtls_entropy_context mtls_entropy;

//    Session mSession("keket", "dalsikeket", &mtls_entropy);

//    Messages messages(nullptr, 0);

//    QString daco = messages.createRegularMessage(mSession, "KOKOTINA");

//    qDebug() << daco;

}
<|endoftext|>


<commit_before>/**
 * @file   AddTaskForwarddNdeta.C
 * @author Christian Holm Christensen <cholm@nbi.dk>
 * @date   Fri Jan 28 10:22:26 2011
 *
 * @brief Script to add a multiplicity task for the central
 *        @f$\eta@f$ region
 *
 *
 * @ingroup pwg2_forward_scripts_tasks
 */
/**
 * Create the Forward @f$ dN/d\eta@f$ analysis task
 *
 * @param trig      Trigger to use
 * @param vzMin     Smallest @f$ v_z@f$
 * @param vzMax     Biggest @f$ v_z@f$
 * @param useCent   Whether to use the centrality or not
 * @param scheme    Normalisation scheme
 * @param cutEdges  Whether to cut edges when rebinning
 *
 * @return Newly created and configured task
 *
 * @ingroup pwg2_forward_dndeta
 */
AliAnalysisTask*
AddTaskForwarddNdeta(const char* trig     = "INEL",
		     Double_t    vzMin    = -10,
		     Double_t    vzMax    = +10,
		     Bool_t      useCent  = false,
		     const char* scheme   = 0,
		     Bool_t      cutEdges = false)
{
  // --- Analysis manager --------------------------------------------
  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();

  // --- Fix up physics selection to give proper A,C, and E triggers -
  AliInputEventHandler* ih =
    static_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
  AliPhysicsSelection* ps =
    static_cast<AliPhysicsSelection*>(ih->GetEventSelection());

  // Ignore trigger class when selecting events.  This mean that we
  // get offline+(A,C,E) events too
  ps->SetSkipTriggerClassSelection(true);

  // --- Make our object ---------------------------------------------
  AliForwarddNdetaTask* task = new AliForwarddNdetaTask("Forward");
  // Set the vertex range to use
  task->SetVertexRange(vzMin, vzMax);
  // Set the trigger mask to use (INEL,INEL>0,NSD)
  task->SetTriggerMask(trig);
  // Whether to cut edges when re-binning
  task->SetCutEdges(cutEdges);
  // Bit mask of
  //
  //    kNone           Normalise to accepted events
  //    kEventLevel     Normalise to all events in selected range
  //    kAltEventLevel  Normalise to all events in selected range
  //    kBackground     Also correct for background triggers
  //    kShape          Correct shape
  //
  // kNone, kEventLevel, and kAltEventLevel are mutually exclusive.
  // If neither kEventLevel, nor kAltEventLevel is specified, then
  // kNone is assumed.  kBackground (when implemented) only makes
  // sense with kEventLevel and kAltEventLevel.  Furthermore, there
  // are some constants that encode the common cases
  //
  //    kFull    = kEventLevel |  kBackground | kShape
  //    kAltFull = kAltEventLevel |  kBackground | kShape
  //
  // Default is kFull
  task->SetNormalizationScheme(AliBasedNdetaTask::kFull);
  if (scheme) task->SetNormalizationScheme(scheme);
  // Set the centrality bins to use.  These are mutually exclusive.
  // Note, that a bin specified as a-b, covers the interval from a,
  // inclusive to b exclusive.  An upper bound of 100 is treated
  // especially, and the upper bound is inclusive in that case .
  if (useCent) {
    Short_t bins[] = { 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
    task->SetCentralityAxis(11, bins);
  }
  mgr->AddTask(task);

  // --- create containers for input/output --------------------------
  AliAnalysisDataContainer *sums =
    mgr->CreateContainer("ForwardSums", TList::Class(),
			 AliAnalysisManager::kOutputContainer,
			 AliAnalysisManager::GetCommonFileName());
  AliAnalysisDataContainer *output =
    mgr->CreateContainer("ForwardResults", TList::Class(),
			 AliAnalysisManager::kParamContainer,
			 AliAnalysisManager::GetCommonFileName());

  // --- connect input/output ----------------------------------------
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 1, sums);
  mgr->ConnectOutput(task, 2, output);

  return task;
}

//________________________________________________________________________
//
// EOF
//
<commit_msg>Whoops - forgot to delete some code<commit_after>/**
 * @file   AddTaskForwarddNdeta.C
 * @author Christian Holm Christensen <cholm@nbi.dk>
 * @date   Fri Jan 28 10:22:26 2011
 *
 * @brief Script to add a multiplicity task for the central
 *        @f$\eta@f$ region
 *
 *
 * @ingroup pwg2_forward_scripts_tasks
 */
/**
 * Create the Forward @f$ dN/d\eta@f$ analysis task
 *
 * @param trig      Trigger to use
 * @param vzMin     Smallest @f$ v_z@f$
 * @param vzMax     Biggest @f$ v_z@f$
 * @param useCent   Whether to use the centrality or not
 * @param scheme    Normalisation scheme
 * @param cutEdges  Whether to cut edges when rebinning
 *
 * @return Newly created and configured task
 *
 * @ingroup pwg2_forward_dndeta
 */
AliAnalysisTask*
AddTaskForwarddNdeta(const char* trig     = "INEL",
		     Double_t    vzMin    = -10,
		     Double_t    vzMax    = +10,
		     Bool_t      useCent  = false,
		     const char* scheme   = 0,
		     Bool_t      cutEdges = false)
{
  // --- Analysis manager --------------------------------------------
  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();

  // --- Make our object ---------------------------------------------
  AliForwarddNdetaTask* task = new AliForwarddNdetaTask("Forward");
  // Set the vertex range to use
  task->SetVertexRange(vzMin, vzMax);
  // Set the trigger mask to use (INEL,INEL>0,NSD)
  task->SetTriggerMask(trig);
  // Whether to cut edges when re-binning
  task->SetCutEdges(cutEdges);
  // Bit mask of
  //
  //    kNone           Normalise to accepted events
  //    kEventLevel     Normalise to all events in selected range
  //    kAltEventLevel  Normalise to all events in selected range
  //    kBackground     Also correct for background triggers
  //    kShape          Correct shape
  //
  // kNone, kEventLevel, and kAltEventLevel are mutually exclusive.
  // If neither kEventLevel, nor kAltEventLevel is specified, then
  // kNone is assumed.  kBackground (when implemented) only makes
  // sense with kEventLevel and kAltEventLevel.  Furthermore, there
  // are some constants that encode the common cases
  //
  //    kFull    = kEventLevel |  kBackground | kShape
  //    kAltFull = kAltEventLevel |  kBackground | kShape
  //
  // Default is kFull
  task->SetNormalizationScheme(AliBasedNdetaTask::kFull);
  if (scheme) task->SetNormalizationScheme(scheme);
  // Set the centrality bins to use.  These are mutually exclusive.
  // Note, that a bin specified as a-b, covers the interval from a,
  // inclusive to b exclusive.  An upper bound of 100 is treated
  // especially, and the upper bound is inclusive in that case .
  if (useCent) {
    Short_t bins[] = { 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
    task->SetCentralityAxis(11, bins);
  }
  mgr->AddTask(task);

  // --- create containers for input/output --------------------------
  AliAnalysisDataContainer *sums =
    mgr->CreateContainer("ForwardSums", TList::Class(),
			 AliAnalysisManager::kOutputContainer,
			 AliAnalysisManager::GetCommonFileName());
  AliAnalysisDataContainer *output =
    mgr->CreateContainer("ForwardResults", TList::Class(),
			 AliAnalysisManager::kParamContainer,
			 AliAnalysisManager::GetCommonFileName());

  // --- connect input/output ----------------------------------------
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 1, sums);
  mgr->ConnectOutput(task, 2, output);

  return task;
}

//________________________________________________________________________
//
// EOF
//
<|endoftext|>


<commit_before>/**
 *
 *
 * @param system
 * @param sNN
 * @param trigger
 * @param option
 * @param rebinned
 * @param empirical
 */
void
WithSysError(const TString&  system,
	     UShort_t        sNN,
	     TString&        trigger,
	     const Option_t* option="e5",
	     Bool_t          rebinned=true,
	     Bool_t          export=true,
	     Bool_t          empirical=true,
	     Bool_t          alsoLog=true)
{
  // --- Search path -------------------------------------------------
  const char* fwd = 0;
  if (gSystem->Getenv("FWD"))
    fwd = gSystem->Getenv("FWD");
  else if (gSystem->Getenv("ANA_SRC"))
    fwd = gSystem->Getenv("ANA_SRC");
  else
    fwd = gSystem->ExpandPathName("$ALICE_PHYSICS/PWGLF/FORWARD/analysis2");
  gROOT->SetMacroPath(Form("%s:%s/dndeta:%s/gse:%s/scripts",
			   gROOT->GetMacroPath(), fwd, fwd, fwd));
  gSystem->AddIncludePath(Form("-I%s/dndeta -I%s/gse", fwd,fwd));

  // --- Load code ---------------------------------------------------
  if (!gROOT->GetClass("Drawer"))       gROOT->LoadMacro("Drawer.C+g");
  if (!gROOT->GetClass("GraphSysErr"))  gROOT->LoadMacro("GraphSysErr.C+g");
  if (!gROOT->GetClass("SysErrorAdder"))gROOT->LoadMacro("SysErrorAdder.C+g");

  // --- Reaction key ------------------------------------------------
  TString reac = system;
  reac.ToUpper();
  reac.Insert(reac.Index("P", 1, 1), " ");
  reac.Append(" --> CHARGED X");

  // --- Fix up trigger and efficiency -------------------------------
  const char* trigs[] = { trigger.Data(), 0 };
  const char* exps[]  = { "ALICE", "WIP", 0 };
  Double_t*   effs    = 0;
  if (sNN == 8000 && system.EqualTo("pp", TString::kIgnoreCase)) {
    effs = new Double_t[2];
    effs[1] = 0;
    if (trigger.EqualTo("INEL",TString::kIgnoreCase))
      effs[0] = 0.85;
    else if (trigger.EqualTo("NSD",TString::kIgnoreCase) ||
	     trigger.EqualTo("V0AND",TString::kIgnoreCase)) {
      trigger  = "NSD";
      trigs[0] = "NSD";
      effs[0]  = 0.93;
    }
  }

  // --- Select how to add -------------------------------------------
  SysErrorAdder* adder = 0;
  TString trigLegTitle = ""; // trigger;
  if (trigger.EqualTo("INEL",TString::kIgnoreCase))
    adder = new INELAdder(system, sNN);
  else if (trigger.EqualTo("NSD",TString::kIgnoreCase))
    adder = new NSDAdder(system, sNN);
  else {
    trigLegTitle = "Centralities:";
    adder = new CENTAdder(system, sNN, trigger);
  }

  // --- Canvas ------------------------------------------------------
  TCanvas* c = new TCanvas("C", "C", 1600, 1000);
  c->SetTopMargin(0.01);
  c->SetRightMargin(0.20);
  c->SetLeftMargin(0.12);

  // --- Legend parameters -------------------------------------------
  Double_t    ly2     = 0.98;
  Double_t    lx1     = 0.81;
  Double_t    lx2     = 0.98;
  Double_t    ldy     = 0.2;
  Double_t    ly1     = ly2-(trigLegTitle.IsNull() ? ldy : 2*ldy);
  // --- Legend for triggers -----------------------------------------
  // TLegend* tl = new TLegend(0.15,ly1,0.3,ly2);
  TLegend* tl = new TLegend(lx1,ly1,lx2,ly2, trigLegTitle);
  tl->SetBorderSize(0);
  tl->SetFillStyle(0);
  tl->SetTextColor(Drawer::AliceBlue());
  tl->SetTextFont(42);

  // --- Legend for errors -------------------------------------------
  // TLegend* el = new TLegend(tl->GetX2(),ly1,tl->GetX2()+.2,ly2);
  ly2 = ly1;
  ly1 = ly2-ldy;
  TLegend* el = new TLegend(lx1,ly1,lx2,ly2, "Sys. errors:");
  el->SetBorderSize(0);
  el->SetFillStyle(0);
  el->SetTextColor(Drawer::AliceBlue());
  el->SetTextFont(42);

  // --- Legend for unique names -------------------------------------
  // TLegend* ul = new TLegend(.6,.8,.95,.97);
  ly2 = ly1;
  ly1 = ly2-.5*ldy;
  TLegend* ul = new TLegend(lx1, ly1, lx2, ly2);
  ul->SetBorderSize(0);
  ul->SetFillStyle(0);
  ul->SetTextColor(Drawer::AliceBlue());
  ul->SetTextFont(42);

  // --- Get the data ------------------------------------------------
  TObjArray   u;
  TPair* dataOther = Drawer::GetDataOther(tl, u, system, sNN, trigs,
					  exps, option, rebinned,
					  empirical, effs);
  if (!dataOther || !dataOther->Key()) {
    Error("", "No data found %s", canvas->GetTitle());
    return;
  }
  THStack*     data  = static_cast<THStack*>(dataOther->Key());
  TMultiGraph* other = static_cast<TMultiGraph*>(dataOther->Value());

  // --- Loop over the data ------------------------------------------
  TList* outList = new TList;
  TIter next(data->GetHists());
  TH1* h = 0;
  Bool_t first = true;
  TH1* frame = 0;
  const char* opt = "stack stat quad split west west";
  while ((h = static_cast<TH1*>(next()))) {
    TString n(h->GetName());
    if (n.Contains("syserror", TString::kIgnoreCase)) continue;

    // Color_t col = h->GetMarkerColor();
    // h->SetMarkerColor(col);
    // h->SetLineColor(col);
    // h->SetFillColor(col);
    GraphSysErr* gse = adder->Make(h, (first ? el : 0));
    gse->SetTitle("");
    gse->Draw(Form("%s %s", (first ? "axis" : ""), opt));
    gse->SetKey("laboratory", "CERN");
    gse->SetKey("accelerator", "LHC");
    gse->SetKey("detector", Form("FORWARD%s", rebinned ? "" : "_full"));
    gse->SetKey("reackey", reac);
    gse->SetKey("obskey", "DN/DETARAP");
    gse->SetKey("title", "Systematic study of 1/N dNch/deta over widest possible eta region at the LHC");
    gse->SetKey("author", "CHRISTENSEN");
    gse->SetKey("comment", "We present 1/N dNch/deta over widest possible eta region at the LHC");
    gse->SetKey("dscomment", "The pseudo-rapidity density of charged particle");

    if (export) {
      TString trg = adder->GetTriggerString();
      if (trg.EqualTo("INEL>0")) trg = "INELGt0";
      TString dir(Form("out/%s/%05d/%s", system.Data(),
		       sNN, trg.Data()));
      gSystem->Exec(Form("mkdir -p %s", dir.Data()));

      TFile* file = TFile::Open(Form("%s/%s.root",
				     dir.Data(),
				     gse->GetKey("detector")),
				"RECREATE");
      Info("", "Writing to %s", file->GetPath());
      gse->Write("data");
      file->Write();
      file->Close();
    }

    outList->Add(gse);
    if (first) {
      TMultiGraph* axis = gse->GetMulti();
      frame = axis->GetHistogram();
      frame->SetMinimum(0.1);
      frame->SetMaximum(frame->GetMaximum()*1.1);
      frame->GetYaxis()->SetTitleOffset(1.4);
    }
    // gse->Export(false);
    first = false;
  }

  // --- Draw the others ---------------------------------------------
  if (other) other->Draw("p");

  // --- Build legend of unique names --------------------------------
  TParameter<int>* um =
    new TParameter<int>("PWG-LF/GEO - work in progress", 20);
  um->SetUniqueID(trigLegTitle.IsNull() ? kRed+2 : kBlack);
  u.Add(um);
  Drawer::MakeUniqueLegend(ul, u, 1);
  ul->Draw();
  tl->Draw();
  el->Draw();

  // --- Make a title ------------------------------------------------
  TLatex* ltx = Drawer::MakeTitle(.45, .98, system, sNN, trigger);
  ltx->SetTextAlign(23);
  ltx->SetTextSize(0.04);

  // --- ALICE logo --------------------------------------------------
  if (!gROOT->GetClass("AliceLogo"))
    gROOT->LoadMacro("AliceLogo.C+");

  if (gROOT->GetClass("AliceLogo")) {
    ly1 = ly1-ldy;
    c->Range(0,0,1,1);
    gROOT->ProcessLine("AliceLogo* al = new AliceLogo();");
    gROOT->ProcessLine(Form("al->Draw(0,%f,%f,%f, 0, 0xf);", lx1,ly1,ldy));
  }

  // --- Output to disk ----------------------------------------------
  TString base(Form("%s_%04d_%s", system.Data(), sNN, trigger.Data()));
  TString outName(Form("%s.root", base.Data()));
  TFile* out = TFile::Open(outName.Data(), "RECREATE");
  outList->Write();
  out->Write();
  Info("", "Wrote to %s.root", base.Data());

  c->Modified();
  c->Update();
  c->cd();
  c->Print(Form("%s.pdf", base.Data()));
  c->Print(Form("%s.png", base.Data()));
  c->SaveAs(Form("%s_canvas.root", base.Data()));
  /// c->SaveAs(Form("%s_canvas.C", base.Data()));

  if (trigLegTitle.IsNull() || !alsoLog) return;

  frame->SetMinimum(5);
  frame->SetMaximum(3*frame->GetMaximum());
  c->SetLogy();
  c->Modified();
  c->Update();
  c->cd();
  c->Print(Form("%s_logy.pdf", base.Data()));
  c->Print(Form("%s_logy.png", base.Data()));

}

<commit_msg>Added INEL>0<commit_after>/**
 *
 *
 * @param system
 * @param sNN
 * @param trigger
 * @param option
 * @param rebinned
 * @param empirical
 */
void
WithSysError(const TString&  system,
	     UShort_t        sNN,
	     TString&        trigger,
	     const Option_t* option="e5",
	     Bool_t          rebinned=true,
	     Bool_t          export=true,
	     Bool_t          empirical=true,
	     Bool_t          alsoLog=true)
{
  // --- Search path -------------------------------------------------
  const char* fwd = 0;
  if (gSystem->Getenv("FWD"))
    fwd = gSystem->Getenv("FWD");
  else if (gSystem->Getenv("ANA_SRC"))
    fwd = gSystem->Getenv("ANA_SRC");
  else
    fwd = gSystem->ExpandPathName("$ALICE_PHYSICS/PWGLF/FORWARD/analysis2");
  gROOT->SetMacroPath(Form("%s:%s/dndeta:%s/gse:%s/scripts",
			   gROOT->GetMacroPath(), fwd, fwd, fwd));
  gSystem->AddIncludePath(Form("-I%s/dndeta -I%s/gse", fwd,fwd));

  // --- Load code ---------------------------------------------------
  if (!gROOT->GetClass("Drawer"))       gROOT->LoadMacro("Drawer.C+g");
  if (!gROOT->GetClass("GraphSysErr"))  gROOT->LoadMacro("GraphSysErr.C+g");
  if (!gROOT->GetClass("SysErrorAdder"))gROOT->LoadMacro("SysErrorAdder.C+g");

  // --- Reaction key ------------------------------------------------
  TString reac = system;
  reac.ToUpper();
  reac.Insert(reac.Index("P", 1, 1), " ");
  reac.Append(" --> CHARGED X");

  // --- Fix up trigger and efficiency -------------------------------
  const char* trigs[] = { trigger.Data(), 0 };
  const char* exps[]  = { "ALICE", "WIP", 0 };
  Double_t*   effs    = 0;
  if (sNN == 8000 && system.EqualTo("pp", TString::kIgnoreCase)) {
    effs = new Double_t[2];
    effs[1] = 0;
    if (trigger.EqualTo("INEL",TString::kIgnoreCase))
      effs[0] = 0.85;
    else if (trigger.EqualTo("NSD",TString::kIgnoreCase) ||
	     trigger.EqualTo("V0AND",TString::kIgnoreCase)) {
      trigger  = "NSD";
      trigs[0] = "NSD";
      effs[0]  = 0.93;
    }
  }

  // --- Select how to add -------------------------------------------
  SysErrorAdder* adder = 0;
  TString trigLegTitle = ""; // trigger;
  if (trigger.EqualTo("INEL",TString::kIgnoreCase))
    adder = new INELAdder(system, sNN);
  if (trigger.EqualTo("INELGt0",TString::kIgnoreCase))
    adder = new INELGt0Adder(system, sNN);
  else if (trigger.EqualTo("NSD",TString::kIgnoreCase))
    adder = new NSDAdder(system, sNN);
  else {
    trigLegTitle = "Centralities:";
    adder = new CENTAdder(system, sNN, trigger);
  }

  // --- Canvas ------------------------------------------------------
  TCanvas* c = new TCanvas("C", "C", 1600, 1000);
  c->SetTopMargin(0.01);
  c->SetRightMargin(0.20);
  c->SetLeftMargin(0.12);

  // --- Legend parameters -------------------------------------------
  Double_t    ly2     = 0.98;
  Double_t    lx1     = 0.81;
  Double_t    lx2     = 0.98;
  Double_t    ldy     = 0.2;
  Double_t    ly1     = ly2-(trigLegTitle.IsNull() ? ldy : 2*ldy);
  // --- Legend for triggers -----------------------------------------
  // TLegend* tl = new TLegend(0.15,ly1,0.3,ly2);
  TLegend* tl = new TLegend(lx1,ly1,lx2,ly2, trigLegTitle);
  tl->SetBorderSize(0);
  tl->SetFillStyle(0);
  tl->SetTextColor(Drawer::AliceBlue());
  tl->SetTextFont(42);

  // --- Legend for errors -------------------------------------------
  // TLegend* el = new TLegend(tl->GetX2(),ly1,tl->GetX2()+.2,ly2);
  ly2 = ly1;
  ly1 = ly2-ldy;
  TLegend* el = new TLegend(lx1,ly1,lx2,ly2, "Sys. errors:");
  el->SetBorderSize(0);
  el->SetFillStyle(0);
  el->SetTextColor(Drawer::AliceBlue());
  el->SetTextFont(42);

  // --- Legend for unique names -------------------------------------
  // TLegend* ul = new TLegend(.6,.8,.95,.97);
  ly2 = ly1;
  ly1 = ly2-.5*ldy;
  TLegend* ul = new TLegend(lx1, ly1, lx2, ly2);
  ul->SetBorderSize(0);
  ul->SetFillStyle(0);
  ul->SetTextColor(Drawer::AliceBlue());
  ul->SetTextFont(42);

  // --- Get the data ------------------------------------------------
  TObjArray   u;
  TPair* dataOther = Drawer::GetDataOther(tl, u, system, sNN, trigs,
					  exps, option, rebinned,
					  empirical, effs);
  if (!dataOther || !dataOther->Key()) {
    Error("", "No data found %s", canvas->GetTitle());
    return;
  }
  THStack*     data  = static_cast<THStack*>(dataOther->Key());
  TMultiGraph* other = static_cast<TMultiGraph*>(dataOther->Value());

  // --- Loop over the data ------------------------------------------
  TList* outList = new TList;
  TIter next(data->GetHists());
  TH1* h = 0;
  Bool_t first = true;
  TH1* frame = 0;
  const char* opt = "stack stat quad split west west";
  while ((h = static_cast<TH1*>(next()))) {
    TString n(h->GetName());
    if (n.Contains("syserror", TString::kIgnoreCase)) continue;

    // Color_t col = h->GetMarkerColor();
    // h->SetMarkerColor(col);
    // h->SetLineColor(col);
    // h->SetFillColor(col);
    GraphSysErr* gse = adder->Make(h, (first ? el : 0));
    gse->SetTitle("");
    gse->Draw(Form("%s %s", (first ? "axis" : ""), opt));
    gse->SetKey("laboratory", "CERN");
    gse->SetKey("accelerator", "LHC");
    gse->SetKey("detector", Form("FORWARD%s", rebinned ? "" : "_full"));
    gse->SetKey("reackey", reac);
    gse->SetKey("obskey", "DN/DETARAP");
    gse->SetKey("title", "Systematic study of 1/N dNch/deta over widest possible eta region at the LHC");
    gse->SetKey("author", "CHRISTENSEN");
    gse->SetKey("comment", "We present 1/N dNch/deta over widest possible eta region at the LHC");
    gse->SetKey("dscomment", "The pseudo-rapidity density of charged particle");

    if (export) {
      TString trg = adder->GetTriggerString();
      if (trg.EqualTo("INEL>0")) trg = "INELGt0";
      TString dir(Form("out/%s/%05d/%s", system.Data(),
		       sNN, trg.Data()));
      gSystem->Exec(Form("mkdir -p %s", dir.Data()));

      TFile* file = TFile::Open(Form("%s/%s.root",
				     dir.Data(),
				     gse->GetKey("detector")),
				"RECREATE");
      Info("", "Writing to %s", file->GetPath());
      gse->Write("data");
      file->Write();
      file->Close();
    }

    outList->Add(gse);
    if (first) {
      TMultiGraph* axis = gse->GetMulti();
      frame = axis->GetHistogram();
      frame->SetMinimum(0.1);
      frame->SetMaximum(frame->GetMaximum()*1.1);
      frame->GetYaxis()->SetTitleOffset(1.4);
    }
    // gse->Export(false);
    first = false;
  }

  // --- Draw the others ---------------------------------------------
  if (other) other->Draw("p");

  // --- Build legend of unique names --------------------------------
  TParameter<int>* um =
    new TParameter<int>("PWG-LF/GEO - work in progress", 20);
  um->SetUniqueID(trigLegTitle.IsNull() ? kRed+2 : kBlack);
  u.Add(um);
  Drawer::MakeUniqueLegend(ul, u, 1);
  ul->Draw();
  tl->Draw();
  el->Draw();

  // --- Make a title ------------------------------------------------
  TLatex* ltx = Drawer::MakeTitle(.45, .98, system, sNN, trigger);
  ltx->SetTextAlign(23);
  ltx->SetTextSize(0.04);

  // --- ALICE logo --------------------------------------------------
  if (!gROOT->GetClass("AliceLogo"))
    gROOT->LoadMacro("AliceLogo.C+");

  if (gROOT->GetClass("AliceLogo")) {
    ly1 = ly1-ldy;
    c->Range(0,0,1,1);
    gROOT->ProcessLine("AliceLogo* al = new AliceLogo();");
    gROOT->ProcessLine(Form("al->Draw(0,%f,%f,%f, 0, 0xf);", lx1,ly1,ldy));
  }

  // --- Output to disk ----------------------------------------------
  TString base(Form("%s_%04d_%s", system.Data(), sNN, trigger.Data()));
  TString outName(Form("%s.root", base.Data()));
  TFile* out = TFile::Open(outName.Data(), "RECREATE");
  outList->Write();
  out->Write();
  Info("", "Wrote to %s.root", base.Data());

  c->Modified();
  c->Update();
  c->cd();
  c->Print(Form("%s.pdf", base.Data()));
  c->Print(Form("%s.png", base.Data()));
  c->SaveAs(Form("%s_canvas.root", base.Data()));
  /// c->SaveAs(Form("%s_canvas.C", base.Data()));

  if (trigLegTitle.IsNull() || !alsoLog) return;

  frame->SetMinimum(5);
  frame->SetMaximum(3*frame->GetMaximum());
  c->SetLogy();
  c->Modified();
  c->Update();
  c->cd();
  c->Print(Form("%s_logy.pdf", base.Data()));
  c->Print(Form("%s_logy.png", base.Data()));

}

<|endoftext|>


<commit_before>// Lose Face - An open source face recognition project
// Copyright (C) 2008-2009 David Capello
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
// * Neither the name of the authors nor the names of its contributors
//   may be used to endorse or promote products derived from this
//   software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>

#define VECTOR_WITH_IO
#define SAVE_DATA 1

#ifndef M_PI
#define M_PI		3.14159265358979323846
#endif

#include "Ann.h"
// #include "Chrono.h"

void train_until_mse_is_reached(Mlp& net, Backpropagation& bp, PatternSet& set,
				double target_mse, int show_epochs)
{
  int i = 0;
  while (net.calcMSE(set) >= target_mse) {
    std::random_shuffle(set.begin(), set.end());
    bp.train(set);
    if (show_epochs > 0 && !((i++)%show_epochs))
      std::cout << "MSE=" << net.calcMSE(set) << std::endl;
  }
  std::cout << "MSE=" << net.calcMSE(set) << std::endl;
}

void train_net_adapting_learning_rate(Mlp& net, Backpropagation& bp, PatternSet& set)
{
  int i = 1;
  double lastE, E = net.calcMSE(set);
  Mlp lastNet;

  while (E > 0.1) {
    std::random_shuffle(set.begin(), set.end());

    lastE = E;
    lastNet = net;

    bp.train(set);

    E = net.calcMSE(set);
    while (E > lastE) {
      bp.setLearningRate(bp.getLearningRate()/2.0);
      net = lastNet;
      bp.train(set);
      E = net.calcMSE(set);

      if (!((i++)%1000))
	std::cout << "MSE=" << net.calcMSE(set)
		  << " LR=" << bp.getLearningRate() << std::endl;
    }
    bp.setLearningRate(bp.getLearningRate()*2.0);
  }
}

void normalize_inputs(PatternSet& set,
		      double min_value,
		      double max_value,
		      Vector& min_vector,
		      Vector& max_vector)
{
  if (!set.empty()) {
    min_vector = set[0].getInput();
    max_vector = set[0].getInput();

    for (size_t c=1; c<set.size(); c++) {
      for (size_t i=0; i<set[c].getInput().size(); i++) {
	if (min_vector(i) > set[c].getInput(i)) min_vector(i) = set[c].getInput(i);
	if (max_vector(i) < set[c].getInput(i)) max_vector(i) = set[c].getInput(i);
      }
    }

    for (size_t c=0; c<set.size(); c++)
      for (size_t i=0; i<set[c].getInput().size(); i++) {
	set[c].setInput(i,
			min_value + ((max_value - min_value) *
				     (set[c].getInput(i) - min_vector(i)) /
				     (     max_vector(i) - min_vector(i))));
      }
  }
}

void test_logical_op(const std::string& name,
		     int a_x0, int a_x1, int a_y0,
		     int b_x0, int b_x1, int b_y0,
		     int c_x0, int c_x1, int c_y0,
		     int d_x0, int d_x1, int d_y0)
{
  std::cout << name << std::endl;

  Mlp net(2, 3, 1);
  net.initRandom(0.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.25);
  bp.setMomentum(0.9);

  PatternSet set;
  for (int c=0; c<4; c++) {
    Pattern pat(net.createInput(),
		net.createOutput());
    set.push_back(pat);
  }

  set[0].setInput(0, a_x0);
  set[0].setInput(1, a_x1);
  set[0].setOutput(0, a_y0);

  set[1].setInput(0, b_x0);
  set[1].setInput(1, b_x1);
  set[1].setOutput(0, b_y0);

  set[2].setInput(0, c_x0);
  set[2].setInput(1, c_x1);
  set[2].setOutput(0, c_y0);

  set[3].setInput(0, d_x0);
  set[3].setInput(1, d_x1);
  set[3].setOutput(0, d_y0);

  train_until_mse_is_reached(net, bp, set, 0.001, 10000);

  for (size_t p=0; p<set.size(); p++) {
    Vector hidden, output;
    net.recall(set[p].getInput(), hidden, output);

    std::cout << "  " << set[p].getInput()
	      << " => " << output << std::endl;
  }

#if SAVE_DATA
  {
    std::ofstream f((name + ".dat").c_str());
    for (double x=0.0; x<=1.0; x+=0.01) {
      for (double y=0.0; y<=1.0; y+=0.01) {
	Vector input(2);
	Vector hidden, output;
	input(0) = x;
	input(1) = y;
	net.recall(input, hidden, output);
	f << input(0) << "\t" << input(1) << "\t" << output(0) << "\n";
      }
    }
  }
#endif
}

void test_grid()
{
  std::cout << "grid" << std::endl;

  Mlp net(2, 16, 1);
  net.initRandom(0.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.1);
  bp.setMomentum(0.8);

  PatternSet set;
  for (int y=0; y<=2; ++y) {
    for (int x=0; x<=2; ++x) {
      Pattern pat(net.createInput(),
		  net.createOutput());
      pat.setInput(0, x / 2.0);
      pat.setInput(1, y / 2.0);
      pat.setOutput(0, ((x>y?x-y:y-x)&1) ? 0.0: 1.0);
      set.push_back(pat);
    }
  }

  train_until_mse_is_reached(net, bp, set, 0.01, 1000);

  for (size_t p=0; p<set.size(); p++) {
    Vector hidden, output;
    net.recall(set[p].getInput(), hidden, output);

    std::cout << "  " << set[p].getInput()
	      << " => " << output << std::endl;
  }

#if SAVE_DATA
  {
    std::ofstream f("grid.dat");
    for (double x=0.0; x<=1.0; x+=0.01) {
      for (double y=0.0; y<=1.0; y+=0.01) {
	Vector input(2);
	Vector hidden, output;
	input(0) = x;
	input(1) = y;
	net.recall(input, hidden, output);
	f << input(0) << "\t" << input(1) << "\t" << output(0) << "\n";
      }
    }
  }
#endif
}

void test_sin()
{
  std::cout << "sin(x)\n";

  Mlp net(1, 10, 1);
  net.setHiddenActivationFunction(Tansig());
  net.initRandom(-1.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.001);
  bp.setMomentum(0.1);

  PatternSet set;
  for (int c=0; c<=100; c++) {
    Pattern pat(net.createInput(),
		net.createOutput());

    double x = (M_PI*8) * static_cast<double>(c) / 100.0 - M_PI*4;
    pat.setInput(0, x);
    pat.setOutput(0, std::sin(x));
    set.push_back(pat);
  }

  train_until_mse_is_reached(net, bp, set, 0.01, 100);

#if SAVE_DATA
  {
    std::ofstream f("sin.dat");
    for (int c=-2000; c<4000; ++c) {
      Vector input(1);
      Vector hidden, output;
      input(0) = (M_PI*2) * static_cast<double>(c) / 1000.0 - M_PI;
      net.recall(input, hidden, output);
      f << input(0) << "\t" << output(0) << "\n";
    }
  }
#endif
}

void test_iris()
{
  std::cout << "iris\n";

  Mlp net(4, 3, 3);
  net.initRandom(-1.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.0001);
  // bp.setLearningRate(0.25);
  // bp.setMomentum(0.9);

  std::ifstream f("iris.csv");
  PatternSet set;
  char buf[256];

  while (f.getline(buf, sizeof(buf)).good()) {
    std::istringstream str(buf);

    Pattern pat(net.createInput(),
		net.createOutput());
    char comma;

    for (int c=0; c<4; ++c) {
      double input = 0.0;
      str >> input >> comma;
      pat.setInput(c, input);
    }

    int output;
    str >> output;

    for (int c=0; c<3; ++c)
      pat.setOutput(c, (c == output) ? 1.0: 0.0);

    set.push_back(pat);
  }

  // std::cout << "Patterns: " << set.size() << "\n\n";
  // for (int p=0; p<set.size(); ++p)
  //   std::cout << "Pattern[" << p << "]: " << set[p].getInput() << " => " << set[p].getOutput() << "\n";

  // normalize patterns
  Vector min_vector;
  Vector max_vector;
  normalize_inputs(set, 0.0, 1.0, min_vector, max_vector);

  // go to training
  int max = 0;
  int bestEpoch = 0;
  Mlp theNet;
  for (int c=0; c<1000; ++c) {
    std::random_shuffle(set.begin(), set.end());
    bp.train(set);

    // performance
    int good = 0;
    for (size_t p=0; p<set.size(); ++p) {
      Vector hidden, output;
      net.recall(set[p].getInput(), hidden, output);

      if (output.getMaxPos() == set[p].getOutput().getMaxPos())
	++good;
    }
    if (max < good) {
      max = good;
      bestEpoch = c;
      theNet = net;
    }
    // std::cout << "Epoch=" << c << " Hits=" << ((double)good / (double)set.size()) << " MSE=" << net.calcMSE(set) << std::endl;
  }
  std::cout << "Best Epoch=" << bestEpoch << " Hits=" << ((double)max / (double)set.size()) << std::endl;

  Matrix distribution(3, 3);
  distribution.zero();
  for (size_t p=0; p<set.size(); ++p) {
    Vector hidden, output;
    theNet.recall(set[p].getInput(), hidden, output);
    ++distribution(set[p].getOutput().getMaxPos(), output.getMaxPos());
  }
  std::cout << "class |  0 |  1 |  2 |" << std::endl
	    << "------+----+----+----+" << std::endl;
  for (int i=0; i<3; ++i) {
    std::printf("   %2d | %2d | %2d | %2d |\n", i,
		(int)distribution(i, 0),
		(int)distribution(i, 1),
		(int)distribution(i, 2));
  }
  std::cout << "------+----+----+----+" << std::endl;
}

int main()
{
  srand(1); test_logical_op("AND", 0,0,0, 0,1,0, 1,0,0, 1,1,1);
  srand(1); test_logical_op("OR",  0,0,0, 0,1,1, 1,0,1, 1,1,1);
  srand(1); test_logical_op("XOR", 0,0,0, 0,1,1, 1,0,1, 1,1,0);
  srand(1); test_grid();
  srand(1); test_sin();
  srand(1); test_iris();
  return 0;
}
<commit_msg>Fixed test_iris.<commit_after>// Lose Face - An open source face recognition project
// Copyright (C) 2008-2009 David Capello
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
// * Neither the name of the authors nor the names of its contributors
//   may be used to endorse or promote products derived from this
//   software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

#include <cstdio>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>

#define VECTOR_WITH_IO
#define SAVE_DATA 1

#ifndef M_PI
#define M_PI		3.14159265358979323846
#endif

#include "Ann.h"
// #include "Chrono.h"

void train_until_mse_is_reached(Mlp& net, Backpropagation& bp, PatternSet& set,
				double target_mse, int show_epochs)
{
  int i = 0;
  while (net.calcMSE(set) >= target_mse) {
    std::random_shuffle(set.begin(), set.end());
    bp.train(set);
    if (show_epochs > 0 && !((i++)%show_epochs))
      std::cout << "MSE=" << net.calcMSE(set) << std::endl;
  }
  std::cout << "MSE=" << net.calcMSE(set) << std::endl;
}

void train_net_adapting_learning_rate(Mlp& net, Backpropagation& bp, PatternSet& set)
{
  int i = 1;
  double lastE, E = net.calcMSE(set);
  Mlp lastNet;

  while (E > 0.1) {
    std::random_shuffle(set.begin(), set.end());

    lastE = E;
    lastNet = net;

    bp.train(set);

    E = net.calcMSE(set);
    while (E > lastE) {
      bp.setLearningRate(bp.getLearningRate()/2.0);
      net = lastNet;
      bp.train(set);
      E = net.calcMSE(set);

      if (!((i++)%1000))
	std::cout << "MSE=" << net.calcMSE(set)
		  << " LR=" << bp.getLearningRate() << std::endl;
    }
    bp.setLearningRate(bp.getLearningRate()*2.0);
  }
}

void normalize_inputs(PatternSet& set,
		      double min_value,
		      double max_value,
		      Vector& min_vector,
		      Vector& max_vector)
{
  if (!set.empty()) {
    min_vector = set[0].getInput();
    max_vector = set[0].getInput();

    for (size_t c=1; c<set.size(); c++) {
      for (size_t i=0; i<set[c].getInput().size(); i++) {
	if (min_vector(i) > set[c].getInput(i)) min_vector(i) = set[c].getInput(i);
	if (max_vector(i) < set[c].getInput(i)) max_vector(i) = set[c].getInput(i);
      }
    }

    for (size_t c=0; c<set.size(); c++)
      for (size_t i=0; i<set[c].getInput().size(); i++) {
	set[c].setInput(i,
			min_value + ((max_value - min_value) *
				     (set[c].getInput(i) - min_vector(i)) /
				     (     max_vector(i) - min_vector(i))));
      }
  }
}

void test_logical_op(const std::string& name,
		     int a_x0, int a_x1, int a_y0,
		     int b_x0, int b_x1, int b_y0,
		     int c_x0, int c_x1, int c_y0,
		     int d_x0, int d_x1, int d_y0)
{
  std::cout << name << std::endl;

  Mlp net(2, 3, 1);
  net.initRandom(0.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.25);
  bp.setMomentum(0.9);

  PatternSet set;
  for (int c=0; c<4; c++) {
    Pattern pat(net.createInput(),
		net.createOutput());
    set.push_back(pat);
  }

  set[0].setInput(0, a_x0);
  set[0].setInput(1, a_x1);
  set[0].setOutput(0, a_y0);

  set[1].setInput(0, b_x0);
  set[1].setInput(1, b_x1);
  set[1].setOutput(0, b_y0);

  set[2].setInput(0, c_x0);
  set[2].setInput(1, c_x1);
  set[2].setOutput(0, c_y0);

  set[3].setInput(0, d_x0);
  set[3].setInput(1, d_x1);
  set[3].setOutput(0, d_y0);

  train_until_mse_is_reached(net, bp, set, 0.001, 10000);

  for (size_t p=0; p<set.size(); p++) {
    Vector hidden, output;
    net.recall(set[p].getInput(), hidden, output);

    std::cout << "  " << set[p].getInput()
	      << " => " << output << std::endl;
  }

#if SAVE_DATA
  {
    std::ofstream f((name + ".dat").c_str());
    for (double x=0.0; x<=1.0; x+=0.01) {
      for (double y=0.0; y<=1.0; y+=0.01) {
	Vector input(2);
	Vector hidden, output;
	input(0) = x;
	input(1) = y;
	net.recall(input, hidden, output);
	f << input(0) << "\t" << input(1) << "\t" << output(0) << "\n";
      }
    }
  }
#endif
}

void test_grid()
{
  std::cout << "grid" << std::endl;

  Mlp net(2, 16, 1);
  net.initRandom(0.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.1);
  bp.setMomentum(0.8);

  PatternSet set;
  for (int y=0; y<=2; ++y) {
    for (int x=0; x<=2; ++x) {
      Pattern pat(net.createInput(),
		  net.createOutput());
      pat.setInput(0, x / 2.0);
      pat.setInput(1, y / 2.0);
      pat.setOutput(0, ((x>y?x-y:y-x)&1) ? 0.0: 1.0);
      set.push_back(pat);
    }
  }

  train_until_mse_is_reached(net, bp, set, 0.01, 1000);

  for (size_t p=0; p<set.size(); p++) {
    Vector hidden, output;
    net.recall(set[p].getInput(), hidden, output);

    std::cout << "  " << set[p].getInput()
	      << " => " << output << std::endl;
  }

#if SAVE_DATA
  {
    std::ofstream f("grid.dat");
    for (double x=0.0; x<=1.0; x+=0.01) {
      for (double y=0.0; y<=1.0; y+=0.01) {
	Vector input(2);
	Vector hidden, output;
	input(0) = x;
	input(1) = y;
	net.recall(input, hidden, output);
	f << input(0) << "\t" << input(1) << "\t" << output(0) << "\n";
      }
    }
  }
#endif
}

void test_sin()
{
  std::cout << "sin(x)\n";

  Mlp net(1, 10, 1);
  net.setHiddenActivationFunction(Tansig());
  net.initRandom(-1.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.001);
  bp.setMomentum(0.1);

  PatternSet set;
  for (int c=0; c<=100; c++) {
    Pattern pat(net.createInput(),
		net.createOutput());

    double x = (M_PI*8) * static_cast<double>(c) / 100.0 - M_PI*4;
    pat.setInput(0, x);
    pat.setOutput(0, std::sin(x));
    set.push_back(pat);
  }

  train_until_mse_is_reached(net, bp, set, 0.01, 100);

#if SAVE_DATA
  {
    std::ofstream f("sin.dat");
    for (int c=-2000; c<4000; ++c) {
      Vector input(1);
      Vector hidden, output;
      input(0) = (M_PI*2) * static_cast<double>(c) / 1000.0 - M_PI;
      net.recall(input, hidden, output);
      f << input(0) << "\t" << output(0) << "\n";
    }
  }
#endif
}

void test_iris()
{
  std::cout << "iris\n";

  Mlp net(4, 3, 3);
  net.initRandom(0.0, 1.0);

  Backpropagation bp(net);
  bp.setLearningRate(0.2);
  bp.setMomentum(0.1);

  std::ifstream f("iris.csv");
  PatternSet set;
  char buf[256];

  while (f.getline(buf, sizeof(buf)).good()) {
    std::istringstream str(buf);

    Pattern pat(net.createInput(),
		net.createOutput());
    char comma;

    for (int c=0; c<4; ++c) {
      double input = 0.0;
      str >> input >> comma;
      pat.setInput(c, input);
    }

    int output;
    str >> output;

    for (int c=0; c<3; ++c)
      pat.setOutput(c, (c == output) ? 1.0: 0.0);

    set.push_back(pat);
  }

  // std::cout << "Patterns: " << set.size() << "\n\n";
  // for (int p=0; p<set.size(); ++p)
  //   std::cout << "Pattern[" << p << "]: " << set[p].getInput() << " => " << set[p].getOutput() << "\n";

  // normalize patterns
  Vector min_vector;
  Vector max_vector;
  normalize_inputs(set, 0.0, 1.0, min_vector, max_vector);

  // go to training
  int max = 0;
  int bestEpoch = 0;
  Mlp theNet;
  for (int c=0; c<1000; ++c) {
    std::random_shuffle(set.begin(), set.end());
    bp.train(set);

    // performance
    int good = 0;
    for (size_t p=0; p<set.size(); ++p) {
      Vector hidden, output;
      net.recall(set[p].getInput(), hidden, output);

      if (output.getMaxPos() == set[p].getOutput().getMaxPos())
	++good;
    }
    if (max < good) {
      max = good;
      bestEpoch = c;
      theNet = net;
    }
    // std::cout << "Epoch=" << c << " Hits=" << ((double)good / (double)set.size()) << " MSE=" << net.calcMSE(set) << std::endl;
  }
  std::cout << "Best Epoch=" << bestEpoch << " Hits=" << ((double)max / (double)set.size()) << std::endl;

  Matrix distribution(3, 3);
  distribution.zero();
  for (size_t p=0; p<set.size(); ++p) {
    Vector hidden, output;
    theNet.recall(set[p].getInput(), hidden, output);
    ++distribution(set[p].getOutput().getMaxPos(), output.getMaxPos());
  }
  std::cout << "class |  0 |  1 |  2 |" << std::endl
	    << "------+----+----+----+" << std::endl;
  for (int i=0; i<3; ++i) {
    std::printf("   %2d | %2d | %2d | %2d |\n", i,
		(int)distribution(i, 0),
		(int)distribution(i, 1),
		(int)distribution(i, 2));
  }
  std::cout << "------+----+----+----+" << std::endl;
}

int main()
{
  srand(1); test_logical_op("AND", 0,0,0, 0,1,0, 1,0,0, 1,1,1);
  srand(1); test_logical_op("OR",  0,0,0, 0,1,1, 1,0,1, 1,1,1);
  srand(1); test_logical_op("XOR", 0,0,0, 0,1,1, 1,0,1, 1,1,0);
  srand(1); test_grid();
  srand(1); test_sin();
  srand(1); test_iris();
  return 0;
}
<|endoftext|>