/** @id $Id$

   This file has been added:
     - by bootstrap.sh
     - on Wed, 24 August 2016 16:36:14 +0200

*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#include <neuron.hxx>

#include <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/XmlOutputter.h>
#include <fstream>

/// @todo Rename DummyTest and DummyTest::dummy()
/// @todo Write test cases
class NeuroNetTest: public CppUnit::TestFixture { 
  public:
    void simplexor() {
      NeuroNet<float, 2, 1> neuronet;
      Matrix<float, 1, 2> in[] = {{1, 1},
                                  {1, -1},
                                  {-1, 1},
                                  {-1, -1}};
      Matrix<float, 1, 1> out[] = {-1,
                                   1,
                                   1,
                                   -1};
      for (int step(0); step<10; ++step)
        for (int i(0); i<sizeof(in)/sizeof(*in); ++i)
          for (int rep(0); rep<10; ++rep)
            auto res(neuronet.learn(in[i], out[i]));
      for (int i(0); i<sizeof(in)/sizeof(*in); ++i) {
        std::cout<<in[i]<<" → "<<out[i]<<" ~ "
                 <<neuronet(in[i]).apply([](float&v){
                     v = v<0 ? -1.0 : 1.0;
                   })<<std::endl;
        auto res(neuronet(in[i])
                 .apply([](float&v){
                     std::cout<<"v="<<v<<std::endl;
                     v = v<0 ? -1.0 : 1.0;
                   }));
        CPPUNIT_ASSERT_EQUAL(out[i], res);
      }
    }
    CPPUNIT_TEST_SUITE(NeuroNetTest);
    CPPUNIT_TEST(simplexor);
    CPPUNIT_TEST_SUITE_END();
};
CPPUNIT_TEST_SUITE_REGISTRATION(NeuroNetTest);

int main(int argc, char** argv) try {
  std::ofstream ofs((*argv+std::string(".xml")).c_str());
  CppUnit::TextUi::TestRunner runner;
  runner.setOutputter(new CppUnit::XmlOutputter(&runner.result(), ofs));
  runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
  return runner.run() ? 0 : 1;
 } catch (std::exception& e) {
  std::cerr<<"***Exception: "<<e.what()<<std::endl;
  return 1;
 }
