<commit_before>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include <iostream>
#include <sstream>

#include "db/test/Test.h"
#include "db/test/Tester.h"
#include "db/test/TestRunner.h"
#include "db/rt/DynamicObject.h"
#include "db/rt/DynamicObjectIterator.h"
#include "db/modest/Kernel.h"
#include "db/event/Observable.h"
#include "db/event/ObserverDelegate.h"
#include "db/event/EventController.h"
#include "db/event/EventWaiter.h"
#include "db/rt/Runnable.h"

using namespace std;
using namespace db::test;
using namespace db::event;
using namespace db::modest;
using namespace db::rt;

class TestObserver : public Observer
{
public:
   int events;
   int event1;
   int event2;
   int event3;
   int event4;

   ObserverDelegate<TestObserver> delegate1;
   ObserverDelegate<TestObserver> delegate2;
   ObserverDelegate<TestObserver> delegate3;
   ObserverDelegate<TestObserver> delegate4;

   TestObserver() :
      delegate1(this, &TestObserver::handleEvent1),
      delegate2(this, &TestObserver::handleEvent2),
      delegate3(this, &TestObserver::handleEvent3),
      delegate4(this, &TestObserver::handleEvent4)
   {
      events = 0;
      event1 = 0;
      event2 = 0;
      event3 = 0;
      event4 = 0;
   }

   virtual ~TestObserver()
   {
   }

   virtual void eventOccurred(Event& e)
   {
      events++;
   }

   virtual void handleEvent1(Event& e)
   {
      event1++;
   }

   virtual void handleEvent2(Event& e)
   {
      event2++;
   }

   virtual void handleEvent3(Event& e)
   {
      event3++;
   }

   virtual void handleEvent4(Event& e)
   {
      if(e["id"]->getUInt64() == 3)
      {
         event3++;
      }
      else if(e["id"]->getUInt64() == 4)
      {
         event4++;
      }
   }
};

void runEventTest(TestRunner& tr)
{
   tr.test("Event");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create observable and observer
   Observable observable;
   TestObserver observer;

   // register observer and start observable
   observable.registerObserver(&observer, 1);
   observable.start(&k);

   // create and schedule events
   Event e1;
   Event e2;
   Event e3;
   e1["name"] = "Event1";
   e2["name"] = "Event2";
   e3["name"] = "Event3";
   observable.schedule(e1, 1);
   observable.schedule(e2, 1);
   observable.schedule(e3, 1);

   // wait for a second
   Thread::sleep(1000);

   assert(observer.events == 3);

   // stop observable
   observable.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.pass();
}

void runObserverDelegateTest(TestRunner& tr)
{
   tr.test("ObserverDelegate");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create observable and observers
   Observable observable;
   TestObserver observer;

   // register observers and start observable
   observable.registerObserver(&observer.delegate1, 1);
   observable.registerObserver(&observer.delegate2, 2);
   observable.registerObserver(&observer.delegate3, 3);
   observable.registerObserver(&observer.delegate4, 4);
   observable.addTap(3, 4);
   observable.start(&k);

   // create and schedule events
   Event e1;
   Event e2;
   Event e3;
   Event e4;
   e1["name"] = "Event1";
   e2["name"] = "Event2";
   e3["name"] = "Event3";
   e4["name"] = "Event4";
   observable.schedule(e1, 1);
   observable.schedule(e2, 2);
   observable.schedule(e3, 3);
   observable.schedule(e4, 4);

   // wait for a second
   Thread::sleep(1000);

   assert(observer.event1 == 1);
   assert(observer.event2 == 1);
   assert(observer.event3 == 2);
   assert(observer.event4 == 1);

   // stop observable
   observable.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.pass();
}

void runEventControllerTest(TestRunner& tr)
{
   tr.test("EventController");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create event controller
   EventController ec;

   // create observers
   TestObserver observer;

   DynamicObject types;
   // string type
   ec.registerObserver(&observer.delegate1, "event1");
   // DynamicObject array of string types
   types[0] = "event2";
   ec.registerObserver(&observer.delegate2, types);
   types[0] = "event3";
   ec.registerObserver(&observer.delegate3, types);
   types[0] = "event4";
   ec.registerObserver(&observer.delegate4, types);

   types[0] = "event1";
   ec.registerObserver(&observer, types);

   // add parent events
   ec.addParent("event2", "event1");
   ec.addParent("event3", "event1");
   ec.addParent("event4", "event3");

   // start event controller
   ec.start(&k);

   // create and schedule events
   Event e1;
   Event e2;
   Event e3;
   Event e4;
   e1["type"] = "event1";
   e2["type"] = "event2";
   e3["type"] = "event3";
   e4["type"] = "event4";
   ec.schedule(e1);
   ec.schedule(e2);
   ec.schedule(e3);
   ec.schedule(e4);

   // wait for a second
   Thread::sleep(1000);

   // check messages
   assert(observer.events == 4);
   assert(observer.event1 == 4);
   assert(observer.event2 == 1);
   assert(observer.event3 == 2);
   assert(observer.event4 == 1);

   // stop event controller
   ec.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.pass();
}

#define DBTDONE "db.test.done"
class TestEventTrigger : public virtual Object, public Runnable
{
public:
   int mSleepMS;
   EventController *mEC;

   TestEventTrigger(EventController* ec)
   {
      mEC = ec;
      mSleepMS = -1;
   }

   virtual ~TestEventTrigger()
   {
   }

   virtual void run()
   {
      // wait a bit
      if(mSleepMS >= 0)
      {
         Thread::sleep(mSleepMS);
      }

      Event e;
      e["type"] = DBTDONE;
      mEC->schedule(e);
   }
};

void runEventWaiterTest(TestRunner& tr)
{
   tr.group("EventWaiter");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create event controller
   EventController ec;

   // start event controller
   ec.start(&k);

   tr.test("quick fire");
   {
      // create a waiter, start, and wait
      EventWaiter ew(&ec);
      ew.start(DBTDONE);

      // create a thread to post event
      TestEventTrigger trigger(&ec);
      Thread t(&trigger);
      t.start();

      bool gotev = ew.waitForEvent();
      // pass if we get past with event
      assert(gotev);
      // stop to unreg event
      ew.stop();
   }
   tr.pass();

   tr.test("delay fire");
   {
      // create a waiter, start, and wait
      EventWaiter ew(&ec);
      ew.start(DBTDONE);

      // create a thread to post event
      TestEventTrigger trigger(&ec);
      trigger.mSleepMS = 1000;
      Thread t(&trigger);
      t.start();

      bool gotev = ew.waitForEvent();
      // pass if we get past with event
      assert(gotev);
      // stop to unreg event
      ew.stop();
   }
   tr.pass();

   // stop event controller
   ec.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.ungroup();
}

class DbEventTester : public db::test::Tester
{
public:
   DbEventTester()
   {
      setName("event");
   }

   /**
    * Run automatic unit tests.
    */
   virtual int runAutomaticTests(TestRunner& tr)
   {
      runEventTest(tr);
      runObserverDelegateTest(tr);
      runEventControllerTest(tr);
      runEventWaiterTest(tr);
      return 0;
   }

   /**
    * Runs interactive unit tests.
    */
   virtual int runInteractiveTests(TestRunner& tr)
   {
      return 0;
   }
};

#ifndef DB_TEST_NO_MAIN
DB_TEST_MAIN(DbEventTester)
#endif
<commit_msg>Fixed leak in test-event.<commit_after>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include <iostream>
#include <sstream>

#include "db/test/Test.h"
#include "db/test/Tester.h"
#include "db/test/TestRunner.h"
#include "db/rt/DynamicObject.h"
#include "db/rt/DynamicObjectIterator.h"
#include "db/modest/Kernel.h"
#include "db/event/Observable.h"
#include "db/event/ObserverDelegate.h"
#include "db/event/EventController.h"
#include "db/event/EventWaiter.h"
#include "db/rt/Runnable.h"

using namespace std;
using namespace db::test;
using namespace db::event;
using namespace db::modest;
using namespace db::rt;

class TestObserver : public Observer
{
public:
   int events;
   int event1;
   int event2;
   int event3;
   int event4;

   ObserverDelegate<TestObserver> delegate1;
   ObserverDelegate<TestObserver> delegate2;
   ObserverDelegate<TestObserver> delegate3;
   ObserverDelegate<TestObserver> delegate4;

   TestObserver() :
      delegate1(this, &TestObserver::handleEvent1),
      delegate2(this, &TestObserver::handleEvent2),
      delegate3(this, &TestObserver::handleEvent3),
      delegate4(this, &TestObserver::handleEvent4)
   {
      events = 0;
      event1 = 0;
      event2 = 0;
      event3 = 0;
      event4 = 0;
   }

   virtual ~TestObserver()
   {
   }

   virtual void eventOccurred(Event& e)
   {
      events++;
   }

   virtual void handleEvent1(Event& e)
   {
      event1++;
   }

   virtual void handleEvent2(Event& e)
   {
      event2++;
   }

   virtual void handleEvent3(Event& e)
   {
      event3++;
   }

   virtual void handleEvent4(Event& e)
   {
      if(e["id"]->getUInt64() == 3)
      {
         event3++;
      }
      else if(e["id"]->getUInt64() == 4)
      {
         event4++;
      }
   }
};

void runEventTest(TestRunner& tr)
{
   tr.test("Event");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create observable and observer
   Observable observable;
   TestObserver observer;

   // register observer and start observable
   observable.registerObserver(&observer, 1);
   observable.start(&k);

   // create and schedule events
   Event e1;
   Event e2;
   Event e3;
   e1["name"] = "Event1";
   e2["name"] = "Event2";
   e3["name"] = "Event3";
   observable.schedule(e1, 1);
   observable.schedule(e2, 1);
   observable.schedule(e3, 1);

   // wait for a second
   Thread::sleep(1000);

   assert(observer.events == 3);

   // stop observable
   observable.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.pass();
}

void runObserverDelegateTest(TestRunner& tr)
{
   tr.test("ObserverDelegate");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create observable and observers
   Observable observable;
   TestObserver observer;

   // register observers and start observable
   observable.registerObserver(&observer.delegate1, 1);
   observable.registerObserver(&observer.delegate2, 2);
   observable.registerObserver(&observer.delegate3, 3);
   observable.registerObserver(&observer.delegate4, 4);
   observable.addTap(3, 4);
   observable.start(&k);

   // create and schedule events
   Event e1;
   Event e2;
   Event e3;
   Event e4;
   e1["name"] = "Event1";
   e2["name"] = "Event2";
   e3["name"] = "Event3";
   e4["name"] = "Event4";
   observable.schedule(e1, 1);
   observable.schedule(e2, 2);
   observable.schedule(e3, 3);
   observable.schedule(e4, 4);

   // wait for a second
   Thread::sleep(1000);

   assert(observer.event1 == 1);
   assert(observer.event2 == 1);
   assert(observer.event3 == 2);
   assert(observer.event4 == 1);

   // stop observable
   observable.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.pass();
}

void runEventControllerTest(TestRunner& tr)
{
   tr.test("EventController");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create event controller
   EventController ec;

   // create observers
   TestObserver observer;

   DynamicObject types;
   // string type
   ec.registerObserver(&observer.delegate1, "event1");
   // DynamicObject array of string types
   types[0] = "event2";
   ec.registerObserver(&observer.delegate2, types);
   types[0] = "event3";
   ec.registerObserver(&observer.delegate3, types);
   types[0] = "event4";
   ec.registerObserver(&observer.delegate4, types);

   types[0] = "event1";
   ec.registerObserver(&observer, types);

   // add parent events
   ec.addParent("event2", "event1");
   ec.addParent("event3", "event1");
   ec.addParent("event4", "event3");

   // start event controller
   ec.start(&k);

   // create and schedule events
   Event e1;
   Event e2;
   Event e3;
   Event e4;
   e1["type"] = "event1";
   e2["type"] = "event2";
   e3["type"] = "event3";
   e4["type"] = "event4";
   ec.schedule(e1);
   ec.schedule(e2);
   ec.schedule(e3);
   ec.schedule(e4);

   // wait for a second
   Thread::sleep(1000);

   // check messages
   assert(observer.events == 4);
   assert(observer.event1 == 4);
   assert(observer.event2 == 1);
   assert(observer.event3 == 2);
   assert(observer.event4 == 1);

   // stop event controller
   ec.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.pass();
}

#define DBTDONE "db.test.done"
class TestEventTrigger : public virtual Object, public Runnable
{
public:
   int mSleepMS;
   EventController *mEC;

   TestEventTrigger(EventController* ec)
   {
      mEC = ec;
      mSleepMS = -1;
   }

   virtual ~TestEventTrigger()
   {
   }

   virtual void run()
   {
      // wait a bit
      if(mSleepMS >= 0)
      {
         Thread::sleep(mSleepMS);
      }

      Event e;
      e["type"] = DBTDONE;
      mEC->schedule(e);
   }
};

void runEventWaiterTest(TestRunner& tr)
{
   tr.group("EventWaiter");

   // create kernel and start engine
   Kernel k;
   k.getEngine()->start();

   // create event controller
   EventController ec;

   // start event controller
   ec.start(&k);

   tr.test("quick fire");
   {
      // create a waiter, start, and wait
      EventWaiter ew(&ec);
      ew.start(DBTDONE);

      // create a thread to post event
      TestEventTrigger trigger(&ec);
      Thread t(&trigger);
      t.start();

      bool gotev = ew.waitForEvent();
      // pass if we get past with event
      assert(gotev);
      // stop to unreg event
      ew.stop();

      // join thread
      t.join();
   }
   tr.pass();

   tr.test("delay fire");
   {
      // create a waiter, start, and wait
      EventWaiter ew(&ec);
      ew.start(DBTDONE);

      // create a thread to post event
      TestEventTrigger trigger(&ec);
      trigger.mSleepMS = 1000;
      Thread t(&trigger);
      t.start();

      bool gotev = ew.waitForEvent();
      // pass if we get past with event
      assert(gotev);
      // stop to unreg event
      ew.stop();

      // join thread
      t.join();
   }
   tr.pass();

   // stop event controller
   ec.stop();

   // stop kernel engine
   k.getEngine()->stop();

   tr.ungroup();
}

class DbEventTester : public db::test::Tester
{
public:
   DbEventTester()
   {
      setName("event");
   }

   /**
    * Run automatic unit tests.
    */
   virtual int runAutomaticTests(TestRunner& tr)
   {
      runEventTest(tr);
      runObserverDelegateTest(tr);
      runEventControllerTest(tr);
      runEventWaiterTest(tr);
      return 0;
   }

   /**
    * Runs interactive unit tests.
    */
   virtual int runInteractiveTests(TestRunner& tr)
   {
      return 0;
   }
};

#ifndef DB_TEST_NO_MAIN
DB_TEST_MAIN(DbEventTester)
#endif
<|endoftext|>


<commit_before>// $Id$
// (c) Guido Kanschat
//
// Compute support points

#include <base/quadrature_lib.h>
#include <base/logstream.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>
#include <grid/grid_generator.h>
#include <fe/fe_q.h>
#include <fe/fe_dgq.h>
#include <fe/fe_values.h>
#include <vector>
#include <fstream>
#include <iomanip>
#include <string>

template <int dim>
inline void
check_support (const FiniteElement<dim>& finel, const char* name)
{
  Triangulation<dim> tr;
  GridGenerator::hyper_cube(tr, 0., 1.);
  DoFHandler<dim> dof (tr);
  dof.distribute_dofs (finel);

  std::cout << name << '<' << dim << '>' << " cell support points" << std::endl;

  const std::vector<Point<dim> > &cell_points = finel.get_unit_support_points ();

  for (unsigned int k=0;k<cell_points.size();++k)
    std::cout << std::setprecision(3) << cell_points[k] << std::endl;

  const std::vector<Point<dim-1> > &face_points = finel.get_unit_face_support_points ();
  const std::vector<double> dummy_weights (face_points.size());

  Quadrature<dim-1> q(face_points, dummy_weights);
  QProjector<dim> qp(q, false);

  unsigned int j=0;
  for (unsigned int i=0;i<GeometryInfo<dim>::faces_per_cell;++i)
    {
      std::cout << name << '<' << dim << '>' << " face " << i << " support points" << std::endl;

      for (unsigned int k=0;k<face_points.size();++k)
	std::cout << std::setprecision(3) << qp.point(j++)
	     << std::endl;
    }
}

template <int dim>
inline void
check_matrices (FiniteElement<dim>& fe, const char* name)
{
  std::cout << name << '<' << dim << '>' << " constraint " << std::endl;
  fe.constraints().print_formatted (std::cout, 7, false, 10, "~");

  for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
    {
      std::cout << name << '<' << dim << '>' << " restriction " << i << std::endl;
      fe.restrict(i).print_formatted (std::cout, 3, false, 6, "~");
      std::cout << name << '<' << dim << '>' << " embedding " << i << std::endl;
      fe.prolongate(i).print_formatted (std::cout, 3, false, 6, "~");
    }
}

#define CHECK_S(EL,deg,dim)   { FE_ ## EL<dim> EL(deg); check_support(EL, #EL #deg); }
#define CHECK_M(EL,deg,dim)   { FE_ ## EL<dim> EL(deg); check_matrices(EL, #EL #deg); }
#define CHECK_ALL(EL,deg,dim) { FE_ ## EL<dim> EL(deg); check_support(EL, #EL #deg); check_matrices(EL,#EL #deg); }

int
main()
{
  CHECK_M(DGQ,0,2);
  CHECK_M(DGQ,1,2);
  CHECK_M(DGQ,2,2);
  CHECK_M(DGQ,3,2);
  CHECK_M(DGQ,4,2);
  CHECK_ALL(Q,1,2);
  CHECK_ALL(Q,2,2);
  CHECK_ALL(Q,3,2);
  CHECK_ALL(Q,4,2);
  CHECK_M(DGQ,0,3);
  CHECK_M(DGQ,1,3);
  CHECK_M(DGQ,2,3);
  CHECK_M(DGQ,3,3);
  CHECK_M(DGQ,4,3);
  CHECK_ALL(Q,1,3);
  CHECK_ALL(Q,2,3);
//  CHECK_ALL(Q,3,2);
//  CHECK_ALL(Q,4,2);
  return 0;
}
<commit_msg>Bring test up to date.<commit_after>// $Id$
// (c) Guido Kanschat
//
// Compute support points

#include <base/quadrature_lib.h>
#include <base/logstream.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>
#include <grid/grid_generator.h>
#include <fe/fe_q.h>
#include <fe/fe_dgq.h>
#include <fe/fe_dgp.h>
#include <fe/fe_system.h>
#include <fe/fe_values.h>
#include <vector>
#include <fstream>
#include <iomanip>
#include <string>

template <typename number>
void print_formatted (const FullMatrix<number> &A,
		      const unsigned int        precision,
		      const unsigned int        width)
{
  for (unsigned int i=0; i<A.m(); ++i)
    {
      for (unsigned int j=0; j<A.n(); ++j)
	{
	  if (A(i,j) != 0)
	    deallog << std::setw(width) << setprecision(precision)
		    << A(i,j);
	  else
	    deallog << std::setw(width) << setprecision(precision)
		    << "~";
	  deallog << ' ';
	};
      deallog << std::endl;
    };
};

template <int dim>
inline void
check_support (const FiniteElement<dim>& finel, const char* name)
{
  Triangulation<dim> tr;
  GridGenerator::hyper_cube(tr, 0., 1.);
  DoFHandler<dim> dof (tr);
  dof.distribute_dofs (finel);

  deallog << name << '<' << dim << '>' << " cell support points" << std::endl;

  const std::vector<Point<dim> > &cell_points = finel.get_unit_support_points ();

  for (unsigned int k=0;k<cell_points.size();++k)
    deallog << std::setprecision(3) << cell_points[k] << std::endl;

  const std::vector<Point<dim-1> > &face_points = finel.get_unit_face_support_points ();
  const std::vector<double> dummy_weights (face_points.size());

  Quadrature<dim-1> q(face_points, dummy_weights);

  for (unsigned int i=0;i<GeometryInfo<dim>::faces_per_cell;++i)
    {
      std::vector<Point<dim> > q_points (q.get_points().size());
      QProjector<dim>::project_to_face (q, i, q_points);
      Quadrature<dim> qp(q_points);
      deallog << name << '<' << dim << '>' << " face " << i
		<< " support points" << std::endl;

      for (unsigned int k=0; k<face_points.size(); ++k)
	deallog << std::setprecision(3) << qp.point(k)
	     << std::endl;
    }
}

template <int dim>
inline void
check_matrices (FiniteElement<dim>& fe, const char* name)
{
  deallog << name << '<' << dim << '>' << " constraint " << std::endl;
  print_formatted (fe.constraints(), 7, 10);

  for (unsigned int i=0;i<GeometryInfo<dim>::children_per_cell;++i)
    {
      deallog << name << '<' << dim << '>' << " restriction " << i << std::endl;
      print_formatted (fe.restrict(i), 3, 6);
      deallog << name << '<' << dim << '>' << " embedding " << i << std::endl;
      print_formatted (fe.prolongate(i), 3, 6);
    }
}

#define CHECK_S(EL,deg,dim)   { FE_ ## EL<dim> EL(deg); check_support(EL, #EL #deg); }
#define CHECK_M(EL,deg,dim)   { FE_ ## EL<dim> EL(deg); check_matrices(EL, #EL #deg); }
#define CHECK_ALL(EL,deg,dim) { FE_ ## EL<dim> EL(deg); check_support(EL, #EL #deg); \
                                                        check_matrices(EL,#EL #deg); }
#define CHECK_SYS1(sub1,N1,dim) { FESystem<dim> q(sub1, N1); check_support(q, #sub1 #N1); \
                                                             check_matrices(q,#sub1 #N1); }
#define CHECK_SYS2(sub1,N1,sub2,N2,dim) { FESystem<dim> q(sub1, N1, sub2, N2); \
                                          check_support(q, #sub1 #N1 #sub2 #N2); \
                                          check_matrices(q,#sub1 #N1 #sub2 #N2); }
#define CHECK_SYS3(sub1,N1,sub2,N2,sub3,N3,dim) { FESystem<dim> q(sub1, N1, sub2, N2, sub3, N3); \
                                          check_support(q, #sub1 #N1 #sub2 #N2 #sub3 #N3); \
                                          check_matrices(q,#sub1 #N1 #sub2 #N2 #sub3 #N3); }

int
main()
{
  std::ofstream logfile("internals.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  CHECK_M(DGQ,0,2);
  CHECK_M(DGQ,1,2);
  CHECK_M(DGQ,2,2);
  CHECK_M(DGQ,3,2);
  CHECK_M(DGQ,4,2);

  CHECK_M(DGP,0,2);
  CHECK_M(DGP,1,2);
  CHECK_M(DGP,2,2);
  CHECK_M(DGP,3,2);
  CHECK_M(DGP,4,2);

  CHECK_ALL(Q,1,2);
  CHECK_ALL(Q,2,2);
  CHECK_ALL(Q,3,2);

  CHECK_M(DGQ,0,3);
  CHECK_M(DGQ,1,3);
  CHECK_M(DGQ,2,3);

  CHECK_M(DGP,0,3);
  CHECK_M(DGP,1,3);
  CHECK_M(DGP,2,3);

  CHECK_ALL(Q,1,3);
  CHECK_ALL(Q,2,3);

  CHECK_SYS1(FE_Q<2>(1),3,2);
  CHECK_SYS1(FE_DGQ<2>(2),2,2);
  CHECK_SYS1(FE_DGP<2>(3),1,2);

  CHECK_SYS2(FE_Q<2>(1),3,FE_DGQ<2>(2),2,2);
  CHECK_SYS2(FE_DGQ<2>(2),2,FE_DGP<2>(3),1,2);
  CHECK_SYS2(FE_DGP<2>(3),1,FE_DGQ<2>(2),2,2);

  CHECK_SYS3(FE_Q<2>(1),3,FE_DGP<2>(3),1,FE_Q<2>(1),3,2);
  CHECK_SYS3(FE_DGQ<2>(2),2,FE_DGQ<2>(2),2,FE_Q<2>(3),3,2);
  CHECK_SYS3(FE_DGP<2>(3),1,FE_DGP<2>(3),1,FE_Q<2>(2),3,2);

				   // systems of systems

  CHECK_SYS3((FESystem<2>(FE_Q<2>(1),3)), 3,
	     FE_DGP<2>(3), 1,
	     FE_Q<2>(1), 3,
	     2);
  CHECK_SYS3(FE_DGP<2>(3), 1,
	     FESystem<2>(FE_DGP<2>(3),3), 1,
	     FESystem<2>(FE_Q<2>(2),3,
			 FE_DGQ<2>(0),1),2,
	     2);

  return 0;
}
<|endoftext|>


<commit_before>// $Id$
// (c) Wolfgang Bangerth
//
// Some more tests with the Nedelec element, basically using
// multi-element triangulations and check whether interface conditions
// are ok

#include <base/quadrature_lib.h>
#include <base/logstream.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_constraints.h>
#include <dofs/dof_tools.h>
#include <grid/grid_generator.h>
#include <grid/grid_tools.h>
#include <fe/fe_nedelec.h>
#include <fe/fe_values.h>

#include <vector>
#include <fstream>
#include <string>

#define PRECISION 2

template <int dim>
void
plot (const Triangulation<dim> &tr)
{
  deallog << dim << "d, "
          << tr.n_active_cells() << " CELLS" << std::endl;

  FE_Nedelec<dim> fe_ned(1);

  DoFHandler<dim> dof(tr);
  dof.distribute_dofs(fe_ned);

                                   // generate some numbers for the
                                   // degrees of freedom on this mesh
  Vector<double> values (dof.n_dofs());
  for (unsigned int i=0; i<values.size(); ++i)
    values(i) = i;
                                   // then make sure that hanging node
                                   // constraints are taken care of
  ConstraintMatrix cm;
  DoFTools::make_hanging_node_constraints (dof, cm);
  cm.close ();
  cm.distribute (values);

  QTrapez<dim> quadrature;
  std::vector<Vector<double> > shape_values (quadrature.n_quadrature_points,
                                             Vector<double>(dim));
  FEValues<dim> fe(fe_ned, quadrature,
                   update_values|update_q_points);

  for (typename DoFHandler<dim>::active_cell_iterator
         c = dof.begin_active();
       c!=dof.end(); ++c)
    {
      deallog << "  CELL " << c << std::endl;
      fe.reinit(c);
      fe.get_function_values (values, shape_values);

      for (unsigned int q=0; q<quadrature.n_quadrature_points; ++q)
        {
          deallog << "    q=" << q
                  << ", xq=" << fe.quadrature_point(q)
                  << ", f=[";
          for (unsigned int d=0; d<dim; ++d)
            deallog << (d==0 ? "" : " ")
                    << shape_values[q](d);

          deallog << "]" << std::endl;
        };

      deallog << std::endl;
    }
};

template<int dim>
inline void
check ()
{
  FE_Nedelec<dim> fe_ned(1);
  Triangulation<dim> tr;
  GridGenerator::hyper_cube(tr, 0., 1.);

                                   // first everything on a
                                   // once-refined grid
  tr.refine_global (1);
  plot (tr);

                                   // then same with one cell refined
  tr.begin_active()->set_refine_flag ();
  tr.execute_coarsening_and_refinement ();
  plot (tr);
};

int
main()
{
  std::ofstream logfile ("nedelec_2.output");
  logfile.precision (PRECISION);
  logfile.setf(std::ios::fixed);
  deallog.attach(logfile);
  deallog.depth_console(0);

  check<2>();
  check<3>();

  return 0;
}

<commit_msg>Remove unnecessary variable.<commit_after>// $Id$
// (c) Wolfgang Bangerth
//
// Some more tests with the Nedelec element, basically using
// multi-element triangulations and check whether interface conditions
// are ok

#include <base/quadrature_lib.h>
#include <base/logstream.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_constraints.h>
#include <dofs/dof_tools.h>
#include <grid/grid_generator.h>
#include <grid/grid_tools.h>
#include <fe/fe_nedelec.h>
#include <fe/fe_values.h>

#include <vector>
#include <fstream>
#include <string>

#define PRECISION 2

template <int dim>
void
plot (const Triangulation<dim> &tr)
{
  deallog << dim << "d, "
          << tr.n_active_cells() << " CELLS" << std::endl;

  FE_Nedelec<dim> fe_ned(1);

  DoFHandler<dim> dof(tr);
  dof.distribute_dofs(fe_ned);

                                   // generate some numbers for the
                                   // degrees of freedom on this mesh
  Vector<double> values (dof.n_dofs());
  for (unsigned int i=0; i<values.size(); ++i)
    values(i) = i;
                                   // then make sure that hanging node
                                   // constraints are taken care of
  ConstraintMatrix cm;
  DoFTools::make_hanging_node_constraints (dof, cm);
  cm.close ();
  cm.distribute (values);

  QTrapez<dim> quadrature;
  std::vector<Vector<double> > shape_values (quadrature.n_quadrature_points,
                                             Vector<double>(dim));
  FEValues<dim> fe(fe_ned, quadrature,
                   update_values|update_q_points);

  for (typename DoFHandler<dim>::active_cell_iterator
         c = dof.begin_active();
       c!=dof.end(); ++c)
    {
      deallog << "  CELL " << c << std::endl;
      fe.reinit(c);
      fe.get_function_values (values, shape_values);

      for (unsigned int q=0; q<quadrature.n_quadrature_points; ++q)
        {
          deallog << "    q=" << q
                  << ", xq=" << fe.quadrature_point(q)
                  << ", f=[";
          for (unsigned int d=0; d<dim; ++d)
            deallog << (d==0 ? "" : " ")
                    << shape_values[q](d);

          deallog << "]" << std::endl;
        };

      deallog << std::endl;
    }
};

template<int dim>
inline void
check ()
{
  Triangulation<dim> tr;
  GridGenerator::hyper_cube(tr, 0., 1.);

                                   // first everything on a
                                   // once-refined grid
  tr.refine_global (1);
  plot (tr);

                                   // then same with one cell refined
  tr.begin_active()->set_refine_flag ();
  tr.execute_coarsening_and_refinement ();
  plot (tr);
};

int
main()
{
  std::ofstream logfile ("nedelec_2.output");
  logfile.precision (PRECISION);
  logfile.setf(std::ios::fixed);
  deallog.attach(logfile);
  deallog.depth_console(0);

  check<2>();
  check<3>();

  return 0;
}

<|endoftext|>


<commit_before><commit_msg>remove wrong comment<commit_after><|endoftext|>


<commit_before><commit_msg>note that mqv example may run afoul of patents if used in production<commit_after><|endoftext|>


<commit_before><commit_msg>New test case<commit_after><|endoftext|>


<commit_before><commit_msg>test if load_module returns the expected object<commit_after><|endoftext|>


<commit_before>#ifdef WIN32
	#include <intrin.h>
#endif
#include "test2D.hpp"

namespace boom {
	namespace test2d {
		void Narrow::SetUp() {
			base_t::SetUp();
			Narrow_t::Initialize();
		}
		TfSP GenRNode(int id) {
			#define MAKENODE(typ)	case typ::GetCID(): return MakeAsNode<typ>();
			switch(id) {
				MAKENODE(geo2d::AABB)
				MAKENODE(geo2d::Circle)
				default:
					Assert(Trap, false, "unknown collision-id")
			}
			#undef MAKENODE
			return nullptr;
		}
	}
	namespace test {
		using geo2d::PointM;
		using Narrow = test2d::Narrow;
		// 階層構造を含めたNarrowPheseテスト (2D)
		TEST_F(Narrow, RandomTree2D) {
			auto rd = getRand();

			// ランダムに当たり判定階層構造を作る
			using CT = spn::CType<geo2d::Circle, geo2d::AABB>;
			auto c0 = test2d::MakeRandomTree<CT,CT>(rd, 64, 8);
			auto c1 = test2d::MakeRandomTree<CT,CT>(rd, 64, 8);
			auto v0 = test2d::CollectLeaf(c0),
				 v1 = test2d::CollectLeaf(c1);
			// 個別に判定した結果
			bool b0 = false;
			for(auto* p0 : v0) {
				for(auto* p1 : v1) {
					if((b0 |= Narrow_t::Hit(p0, p1, 0)))
						break;
				}
			}
			// ツリー構造で判定した結果
			bool b1 = Narrow_t::Hit(c0.get(), c1.get(), 0);
			// 両者は一致する筈
			ASSERT_EQ(b0, b1);
		}

		template <class T>
		class TfNode : public Narrow {
			public:
				using Narrow::Narrow;
		};
		using TfNodeTypeList = ::testing::Types<geo2d::Circle,
												geo2d::Segment,
												geo2d::Line,
												geo2d::Ray,
												geo2d::Poly,
												geo2d::AABB,
												geo2d::Convex>;
		TYPED_TEST_CASE(TfNode, TfNodeTypeList);

		using namespace spn::test;
		// 単一ノードによる姿勢変換テスト
		TYPED_TEST(TfNode, TFNode2D) {
			auto rd = this->getRand();

			using Shape = TypeParam;
			using ShapeM = geo2d::Model<Shape>;
			// 基本の形状に姿勢変換を掛けた物(=A)と
			// 変換後の座標で直接生成した物(=B)の2種類を用意
			ShapeM s;
			test2d::GenRShape(s, rd);
			spn::Pose2D ps(GenR2Vec(rd, {-1e3f, 1e3f}),
							spn::DegF(rd.template getUniform<float>({-180.f, 180.f})),
							Vec2(rd.template getUniform<float>({1e-2f, 1e2f})));
			auto spA = std::make_shared<geo2d::TfLeaf<Shape>>(s * ps.getToWorld()),
				 spB = std::make_shared<geo2d::TfLeaf<Shape>>(s);
			spB->setPose(ps);

			// サポート写像が一致するか確認
			constexpr int nCheck = 100;
			for(int i=0 ; i<nCheck ; i++) {
				auto dir = spn::test::GenR2Dir(rd);
				auto p0 = spA->im_support(dir);
				auto p1 = spB->im_support(dir);
				ASSERT_LE(p0.distance(p1), 1e-3f);
			}
			for(int i=0 ; i<nCheck ; i++) {
				// 衝突試験用の形状を1つ用意
				ShapeM check;
				test2d::GenRShape(check, rd);
				// 結果は同じになる筈
				using this_t = TfNode<TypeParam>;
				bool bA = this_t::Narrow_t::Hit(spA.get(), &check, 0),
					 bB = this_t::Narrow_t::Hit(spB.get(), &check, 0);
				ASSERT_EQ(bA, bB);
			}
		}
	}
}
<commit_msg>姿勢変換ありのツリー判定テストコード追加<commit_after>#ifdef WIN32
	#include <intrin.h>
#endif
#include "test2D.hpp"

namespace boom {
	namespace test2d {
		void Narrow::SetUp() {
			base_t::SetUp();
			Narrow_t::Initialize();
		}
		TfSP GenRNode(int id) {
			#define MAKENODE(typ)	case typ::GetCID(): return MakeAsNode<typ>();
			switch(id) {
				MAKENODE(geo2d::AABB)
				MAKENODE(geo2d::Circle)
				default:
					Assert(Trap, false, "unknown collision-id")
			}
			#undef MAKENODE
			return nullptr;
		}
	}
	namespace test {
		using geo2d::PointM;
		using Narrow = test2d::Narrow;
		// 階層構造を含めたNarrowPheseテスト (2D)
		TEST_F(Narrow, RandomTree2D) {
			auto rd = getRand();

			// ランダムに当たり判定階層構造を作る
			using CT = spn::CType<geo2d::Circle, geo2d::AABB>;
			auto c0 = test2d::MakeRandomTree<CT,CT>(rd, 64, 8);
			auto c1 = test2d::MakeRandomTree<CT,CT>(rd, 64, 8);
			auto v0 = test2d::CollectLeaf(c0),
				 v1 = test2d::CollectLeaf(c1);
			// 個別に判定した結果
			bool b0 = false;
			for(auto* p0 : v0) {
				for(auto* p1 : v1) {
					if((b0 |= Narrow_t::Hit(p0, p1, 0)))
						break;
				}
			}
			// ツリー構造で判定した結果
			bool b1 = Narrow_t::Hit(c0.get(), c1.get(), 0);
			// 両者は一致する筈
			ASSERT_EQ(b0, b1);
		}

		template <class T>
		class TfNode : public Narrow {
			public:
				using Narrow::Narrow;
		};
		using TfNodeTypeList = ::testing::Types<geo2d::Circle,
												geo2d::Segment,
												geo2d::Line,
												geo2d::Ray,
												geo2d::Poly,
												geo2d::AABB,
												geo2d::Convex>;
		TYPED_TEST_CASE(TfNode, TfNodeTypeList);

		using namespace spn::test;
		// 単一ノードによる姿勢変換テスト
		TYPED_TEST(TfNode, TFNode2D) {
			auto rd = this->getRand();

			using Shape = TypeParam;
			using ShapeM = geo2d::Model<Shape>;
			// 基本の形状に姿勢変換を掛けた物(=A)と
			// 変換後の座標で直接生成した物(=B)の2種類を用意
			ShapeM s;
			test2d::GenRShape(s, rd);
			spn::Pose2D ps(GenR2Vec(rd, {-1e3f, 1e3f}),
							spn::DegF(rd.template getUniform<float>({-180.f, 180.f})),
							Vec2(rd.template getUniform<float>({1e-2f, 1e2f})));
			auto spA = std::make_shared<geo2d::TfLeaf<Shape>>(s * ps.getToWorld()),
				 spB = std::make_shared<geo2d::TfLeaf<Shape>>(s);
			spB->setPose(ps);

			// サポート写像が一致するか確認
			constexpr int nCheck = 100;
			for(int i=0 ; i<nCheck ; i++) {
				auto dir = spn::test::GenR2Dir(rd);
				auto p0 = spA->im_support(dir);
				auto p1 = spB->im_support(dir);
				ASSERT_LE(p0.distance(p1), 1e-3f);
			}
			for(int i=0 ; i<nCheck ; i++) {
				// 衝突試験用の形状を1つ用意
				ShapeM check;
				test2d::GenRShape(check, rd);
				// 結果は同じになる筈
				using this_t = TfNode<TypeParam>;
				bool bA = this_t::Narrow_t::Hit(spA.get(), &check, 0),
					 bB = this_t::Narrow_t::Hit(spB.get(), &check, 0);
				ASSERT_EQ(bA, bB);
			}
		}
		// ツリーノードによる姿勢変換テスト
		TEST_F(Narrow, TfTree2D) {
			auto rd = this->getRand();

			using CTLeaf = spn::CType<geo2d::Circle, geo2d::AABB>;
			using CTNode = spn::CType<geo2d::Circle>;
			auto spA = test2d::MakeRandomTree<CTNode, CTNode>(rd, 64, 8),
				spB = spA->cloneTree();
			auto vA = test2d::CollectLeaf(spA),
				 vB = test2d::CollectLeaf(spB);

			// 基本の形状に姿勢変換を掛けた物(=A)と
			// 変換後の座標で直接生成した物(=B)の2種類を用意
			spn::Pose2D ps(GenR2Vec(rd, {-1e3f, 1e3f}),
							spn::DegF(rd.template getUniform<float>({-180.f, 180.f})),
							Vec2(rd.template getUniform<float>({1e-2f, 1e2f})));
			for(auto& vs : vA) {
				auto* vsp = static_cast<geo2d::TfLeaf<geo2d::Circle>*>(vs);
				vsp->setPose(ps);
			}
			auto& toWorld = ps.getToWorld();
			for(auto& vs : vB) {
				auto* vsp = static_cast<geo2d::TfLeaf<geo2d::Circle>*>(vs);
				static_cast<geo2d::Circle&>(*vsp) = *vsp * toWorld;
			}

			constexpr int nCheck = 5;
			for(int i=0 ; i<nCheck ; i++) {
				auto t0 = test2d::MakeRandomTree<CTNode, CTLeaf>(rd, 64, 8);
				bool bA = Narrow_t::Hit(spA.get(), t0.get(), 0),
					bB = Narrow_t::Hit(spB.get(), t0.get(), 0);
				ASSERT_EQ(bA, bB);
			}
		}
	}
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Mathieu Gautier <mathieu.gautier@cea.fr>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <Eigen/Geometry>
#include <Eigen/LU>
#include <Eigen/SVD>

template<typename Scalar> void quaternion(void)
{
  /* this test covers the following files:
     Quaternion.h
  */

  typedef Matrix<Scalar,3,3> Matrix3;
  typedef Matrix<Scalar,3,1> Vector3;
  typedef Quaternion<Scalar> Quaternionx;
  typedef AngleAxis<Scalar> AngleAxisx;

  Scalar largeEps = test_precision<Scalar>();
  if (internal::is_same<Scalar,float>::value)
    largeEps = 1e-3f;

  Scalar eps = internal::random<Scalar>() * Scalar(1e-2);

  Vector3 v0 = Vector3::Random(),
          v1 = Vector3::Random(),
          v2 = Vector3::Random(),
          v3 = Vector3::Random();

  Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));

  // Quaternion: Identity(), setIdentity();
  Quaternionx q1, q2;
  q2.setIdentity();
  VERIFY_IS_APPROX(Quaternionx(Quaternionx::Identity()).coeffs(), q2.coeffs());
  q1.coeffs().setRandom();
  VERIFY_IS_APPROX(q1.coeffs(), (q1*q2).coeffs());

  // concatenation
  q1 *= q2;

  q1 = AngleAxisx(a, v0.normalized());
  q2 = AngleAxisx(a, v1.normalized());

  // angular distance
  Scalar refangle = internal::abs(AngleAxisx(q1.inverse()*q2).angle());
  if (refangle>Scalar(M_PI))
    refangle = Scalar(2)*Scalar(M_PI) - refangle;

  if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)
  {
    VERIFY(internal::isApprox(q1.angularDistance(q2), refangle, largeEps));
  }

  // rotation matrix conversion
  VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);
  VERIFY_IS_APPROX(q1 * q2 * v2,
    q1.toRotationMatrix() * q2.toRotationMatrix() * v2);

  VERIFY(  (q2*q1).isApprox(q1*q2, largeEps)
        || !(q2 * q1 * v2).isApprox(q1.toRotationMatrix() * q2.toRotationMatrix() * v2));

  q2 = q1.toRotationMatrix();
  VERIFY_IS_APPROX(q1*v1,q2*v1);

  // angle-axis conversion
  AngleAxisx aa = AngleAxisx(q1);
  VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
  VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);

  // from two vector creation
  VERIFY_IS_APPROX( v2.normalized(),(q2.setFromTwoVectors(v1, v2)*v1).normalized());
  VERIFY_IS_APPROX( v1.normalized(),(q2.setFromTwoVectors(v1, v1)*v1).normalized());
  VERIFY_IS_APPROX(-v1.normalized(),(q2.setFromTwoVectors(v1,-v1)*v1).normalized());
  if (internal::is_same<Scalar,double>::value)
  {
    v3 = (v1.array()+eps).matrix();
    VERIFY_IS_APPROX( v3.normalized(),(q2.setFromTwoVectors(v1, v3)*v1).normalized());
    VERIFY_IS_APPROX(-v3.normalized(),(q2.setFromTwoVectors(v1,-v3)*v1).normalized());
  }

  // inverse and conjugate
  VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1);
  VERIFY_IS_APPROX(q1 * (q1.conjugate() * v1), v1);

  // test casting
  Quaternion<float> q1f = q1.template cast<float>();
  VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);
  Quaternion<double> q1d = q1.template cast<double>();
  VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
}

template<typename Scalar> void mapQuaternion(void){
  typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA;
  typedef Map<Quaternion<Scalar> > MQuaternionUA;
  typedef Quaternion<Scalar> Quaternionx;

	EIGEN_ALIGN16 Scalar array1[4];
	EIGEN_ALIGN16 Scalar array2[4];
	EIGEN_ALIGN16 Scalar array3[4+1];
	Scalar* array3unaligned = array3+1;

  MQuaternionA(array1).coeffs().setRandom();
  (MQuaternionA(array2)) = MQuaternionA(array1);
  (MQuaternionUA(array3unaligned)) = MQuaternionA(array1);

  Quaternionx q1 = MQuaternionA(array1);
  Quaternionx q2 = MQuaternionA(array2);
  Quaternionx q3 = MQuaternionUA(array3unaligned);

  VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs());
  VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs());
  #ifdef EIGEN_VECTORIZE
  VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned)));
  #endif
}

void test_geo_quaternion()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( quaternion<float>() );
    CALL_SUBTEST_2( quaternion<double>() );
    CALL_SUBTEST( mapQuaternion<float>() );
    CALL_SUBTEST( mapQuaternion<double>() );
  }
}
<commit_msg>test case for unaligned quaternion<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2009 Mathieu Gautier <mathieu.gautier@cea.fr>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <Eigen/Geometry>
#include <Eigen/LU>
#include <Eigen/SVD>

template<typename Scalar, int Options> void quaternion(void)
{
  /* this test covers the following files:
     Quaternion.h
  */

  typedef Matrix<Scalar,3,3> Matrix3;
  typedef Matrix<Scalar,3,1> Vector3;
  typedef Quaternion<Scalar,Options> Quaternionx;
  typedef AngleAxis<Scalar> AngleAxisx;

  Scalar largeEps = test_precision<Scalar>();
  if (internal::is_same<Scalar,float>::value)
    largeEps = 1e-3f;

  Scalar eps = internal::random<Scalar>() * Scalar(1e-2);

  Vector3 v0 = Vector3::Random(),
          v1 = Vector3::Random(),
          v2 = Vector3::Random(),
          v3 = Vector3::Random();

  Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));

  // Quaternion: Identity(), setIdentity();
  Quaternionx q1, q2;
  q2.setIdentity();
  VERIFY_IS_APPROX(Quaternionx(Quaternionx::Identity()).coeffs(), q2.coeffs());
  q1.coeffs().setRandom();
  VERIFY_IS_APPROX(q1.coeffs(), (q1*q2).coeffs());

  // concatenation
  q1 *= q2;

  q1 = AngleAxisx(a, v0.normalized());
  q2 = AngleAxisx(a, v1.normalized());

  // angular distance
  Scalar refangle = internal::abs(AngleAxisx(q1.inverse()*q2).angle());
  if (refangle>Scalar(M_PI))
    refangle = Scalar(2)*Scalar(M_PI) - refangle;

  if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)
  {
    VERIFY(internal::isApprox(q1.angularDistance(q2), refangle, largeEps));
  }

  // rotation matrix conversion
  VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);
  VERIFY_IS_APPROX(q1 * q2 * v2,
    q1.toRotationMatrix() * q2.toRotationMatrix() * v2);

  VERIFY(  (q2*q1).isApprox(q1*q2, largeEps)
        || !(q2 * q1 * v2).isApprox(q1.toRotationMatrix() * q2.toRotationMatrix() * v2));

  q2 = q1.toRotationMatrix();
  VERIFY_IS_APPROX(q1*v1,q2*v1);

  // angle-axis conversion
  AngleAxisx aa = AngleAxisx(q1);
  VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
  VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);

  // from two vector creation
  VERIFY_IS_APPROX( v2.normalized(),(q2.setFromTwoVectors(v1, v2)*v1).normalized());
  VERIFY_IS_APPROX( v1.normalized(),(q2.setFromTwoVectors(v1, v1)*v1).normalized());
  VERIFY_IS_APPROX(-v1.normalized(),(q2.setFromTwoVectors(v1,-v1)*v1).normalized());
  if (internal::is_same<Scalar,double>::value)
  {
    v3 = (v1.array()+eps).matrix();
    VERIFY_IS_APPROX( v3.normalized(),(q2.setFromTwoVectors(v1, v3)*v1).normalized());
    VERIFY_IS_APPROX(-v3.normalized(),(q2.setFromTwoVectors(v1,-v3)*v1).normalized());
  }

  // inverse and conjugate
  VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1);
  VERIFY_IS_APPROX(q1 * (q1.conjugate() * v1), v1);

  // test casting
  Quaternion<float> q1f = q1.template cast<float>();
  VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);
  Quaternion<double> q1d = q1.template cast<double>();
  VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
}

template<typename Scalar> void mapQuaternion(void){
  typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA;
  typedef Map<Quaternion<Scalar> > MQuaternionUA;
  typedef Quaternion<Scalar> Quaternionx;

  EIGEN_ALIGN16 Scalar array1[4];
  EIGEN_ALIGN16 Scalar array2[4];
  EIGEN_ALIGN16 Scalar array3[4+1];
  Scalar* array3unaligned = array3+1;

  MQuaternionA(array1).coeffs().setRandom();
  (MQuaternionA(array2)) = MQuaternionA(array1);
  (MQuaternionUA(array3unaligned)) = MQuaternionA(array1);

  Quaternionx q1 = MQuaternionA(array1);
  Quaternionx q2 = MQuaternionA(array2);
  Quaternionx q3 = MQuaternionUA(array3unaligned);

  VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs());
  VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs());
  #ifdef EIGEN_VECTORIZE
  VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned)));
  #endif
}

template<typename Scalar> void quaternionAlignment(void){
  typedef Quaternion<Scalar,AutoAlign> QuaternionA;
  typedef Quaternion<Scalar,DontAlign> QuaternionUA;

  EIGEN_ALIGN16 Scalar array1[4];
  EIGEN_ALIGN16 Scalar array2[4];
  EIGEN_ALIGN16 Scalar array3[4+1];
  Scalar* arrayunaligned = array3+1;

  QuaternionA *q1 = ::new(reinterpret_cast<void*>(array1)) QuaternionA;
  QuaternionUA *q2 = ::new(reinterpret_cast<void*>(array2)) QuaternionUA;
  QuaternionUA *q3 = ::new(reinterpret_cast<void*>(arrayunaligned)) QuaternionUA;

  q1->coeffs().setRandom();
  *q2 = *q1;
  *q3 = *q1;

  VERIFY_IS_APPROX(q1->coeffs(), q2->coeffs());
  VERIFY_IS_APPROX(q1->coeffs(), q3->coeffs());
  #ifdef EIGEN_VECTORIZE
  VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(arrayunaligned)) QuaternionA));
  #endif
}

void test_geo_quaternion()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(( quaternion<float,AutoAlign>() ));
    CALL_SUBTEST_2(( quaternion<double,AutoAlign>() ));
    CALL_SUBTEST_3(( quaternion<float,DontAlign>() ));
    CALL_SUBTEST_4(( quaternion<double,DontAlign>() ));
    CALL_SUBTEST_5(( quaternionAlignment<float>() ));
    CALL_SUBTEST_6(( quaternionAlignment<double>() ));
    CALL_SUBTEST( mapQuaternion<float>() );
    CALL_SUBTEST( mapQuaternion<double>() );
  }
}
<|endoftext|>


<commit_before>#include "command.h"
#include "image.h"
#include "algo/loop.h"

#include "image/average_space.h"
#include "interp/linear.h"
#include "interp/nearest.h"
#include "interp/cubic.h"
#include "interp/sinc.h"
#include "filter/reslice.h"

using namespace MR;
using namespace App;

const char* interp_choices[] = { "nearest", "linear", "cubic", "sinc", NULL }; // TODO
const char* space_choices[] = { "voxel", "image1", "image2", "average", NULL };

template <class ValueType>
inline void meansquared(const ValueType& value1, const ValueType& value2, ValueType& cost){
  cost += std::pow (value1 - value2, 2);
}

// TODO: there must be a better way of doing this?
template <class ImageType1, class ImageType2, class TransformType, class OversampleType, class ValueType>
void reslice(size_t interp, ImageType1& input, ImageType2& output, const TransformType& trafo = Adapter::NoTransform, const OversampleType& oversample = Adapter::AutoOverSample, const ValueType out_of_bounds_value = 0.f){
  switch(interp){
    case 0:
      Filter::reslice<Interp::Nearest> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Nearest");
      break;
    case 1:
      Filter::reslice<Interp::Linear> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Linear");
      break;
    case 2:
      Filter::reslice<Interp::Cubic> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Cubic");
      break;
    case 3:
      Filter::reslice<Interp::Sinc> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Sinc");
      break;
    default:
      throw Exception ("Fixme: interpolation value invalid");
  }
}

void usage ()
{
  AUTHOR = "David Raffelt (david.raffelt@florey.edu.au)";

  DESCRIPTION
  + "computes a dissimilarity metric between two images. Currently only the mean squared difference is implemented";

  ARGUMENTS
  + Argument ("image1", "the first input image.").type_image_in ()
  + Argument ("image2", "the second input image.").type_image_in ();

  OPTIONS
  + Option ("space",
        "voxel (default): per voxel "
        "image1: scanner space of image 1 "
        "image2: scanner space of image 2 "
        "average: scanner space of the average affine transformation of image 1 and 2 ")
    +   Argument ("iteration method").type_choice (space_choices)

    + Option ("interp",
        "set the interpolation method to use when reslicing (choices: nearest, linear, cubic, sinc. Default: cubic).")
    + Argument ("method").type_choice (interp_choices)

    + Option ("mask1", "mask for image 1")
    + Argument ("image").type_image_in ()

    + Option ("mask2", "mask for image 2")
    + Argument ("image").type_image_in ()

    + Option ("nonormalisation",
        "do not normalise the dissimilarity metric to the number of voxels.");

}

typedef double value_type;
typedef Image<bool> MaskType;

void run ()
{
  auto input1 = Image<value_type>::open (argument[0]);
  auto input2 = Image<value_type>::open (argument[1]);

  int space = 0;  // voxel
  auto opt = get_options ("space");
  if (opt.size())
    space = opt[0][0];

  MaskType mask1;
  bool use_mask1 = get_options ("mask1").size()==1;
  if (use_mask1)
    mask1 = Image<bool>::open(get_options ("mask1")[0][0]);

  MaskType mask2;
  bool use_mask2 = get_options ("mask2").size()==1;
  if (use_mask2)
    mask2 = Image<bool>::open(get_options ("mask2")[0][0]);

  bool nonormalisation = false;
  if (get_options ("nonormalisation").size())
    nonormalisation = true;
  ssize_t n_voxels = input1.size(0) * input1.size(1) * input1.size(2);

  value_type out_of_bounds_value = 0.0;

  value_type sos = 0.0;
  if (space==0){
    DEBUG("per-voxel");
    check_dimensions (input1, input2);
    if (use_mask1 or use_mask2)
      n_voxels = 0;
    if (use_mask1 and use_mask2){
      for (auto i = Loop() (input1, input2, mask1, mask2); i ;++i)
        if (mask1.value() and mask2.value()){
          n_voxels += 1;
          meansquared<value_type>(input1.value(), input2.value(), sos);
        }
    } else if (use_mask1){
      for (auto i = Loop() (input1, input2, mask1); i ;++i)
        if (mask1.value()){
          n_voxels += 1;
          meansquared<value_type>(input1.value(), input2.value(), sos);
        }
    } else if (use_mask2){
      for (auto i = Loop() (input1, input2, mask2); i ;++i)
        if (mask2.value()){
          n_voxels += 1;
          meansquared<value_type>(input1.value(), input2.value(), sos);
        }
    } else {
      for (auto i = Loop() (input1, input2); i ;++i)
        meansquared<value_type>(input1.value(), input2.value(), sos);
    }
  } else {
    DEBUG("scanner space");
    int interp = 2;  // cubic
    opt = get_options ("interp");
    if (opt.size())
      interp = opt[0][0];

    auto output1 = Header::scratch(input1.original_header(),"-").get_image<value_type>();
    auto output2 = Header::scratch(input2.original_header(),"-").get_image<value_type>();

    MaskType output1mask;
    MaskType output2mask;

    if (space == 1){
      DEBUG("image 1");
      output1 = input1;
      output1mask = mask1;
      output2 = Header::scratch(input1.original_header(),"-").get_image<value_type>();
      output2mask = Header::scratch(input1.original_header(),"-").get_image<bool>();
      {
        LogLevelLatch log_level (0);
        reslice(interp,input2, output2, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        if (use_mask2)
          Filter::reslice<Interp::Nearest> (mask2, output2mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
      }
    }

    if (space == 2) {
      DEBUG("image 2");
      output1 = Header::scratch(input2.original_header(),"-").get_image<value_type>();
      output1mask = Header::scratch(input2.original_header(),"-").get_image<bool>();
      output2 = input2;
      output2mask = mask2;
      {
        LogLevelLatch log_level (0);
        reslice(interp, input1, output1, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        if (use_mask1)
          Filter::reslice<Interp::Nearest> (mask1, output1mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
      }
      n_voxels = input2.size(0) * input2.size(1) * input2.size(2);
    }

    if (space == 3) {
      DEBUG("average space");
      std::vector<Header> headers;
      headers.push_back (input1.original_header());
      headers.push_back (input2.original_header());
      default_type template_res = 1.0;
      auto padding = Eigen::Matrix<default_type, 4, 1>(0, 0, 0, 1.0);
      std::vector<Eigen::Transform<double, 3, Eigen::Projective>> transform_header_with;

      auto template_header = compute_minimum_average_header<double,Eigen::Transform<double, 3, Eigen::Projective>>(headers, template_res, padding, transform_header_with);

      output1 = Header::scratch(template_header,"-").get_image<value_type>();
      output2 = Header::scratch(template_header,"-").get_image<value_type>();
      output1mask = Header::scratch(template_header,"-").get_image<bool>();
      output2mask = Header::scratch(template_header,"-").get_image<bool>();
      {
        LogLevelLatch log_level (0);
        reslice(interp, input1, output1, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        reslice(interp, input2, output2, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        if (use_mask1)
          Filter::reslice<Interp::Nearest> (mask1, output1mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
        if (use_mask2)
          Filter::reslice<Interp::Nearest> (mask2, output2mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
      }
      n_voxels = output1.size(0) * output1.size(1) * output1.size(2);
    }

    if (use_mask1 or use_mask2)
      n_voxels = 0;
    if (use_mask1 and use_mask2){
      for (auto i = Loop() (output1, output2, output1mask, output2mask); i ;++i)
        if (output1mask.value() and output2mask.value()){
          n_voxels += 1;
          meansquared<value_type>(output1.value(), output2.value(), sos);
        }
    } else if (use_mask1){
      for (auto i = Loop() (output1, output2, output1mask); i ;++i)
        if (output1mask.value()){
          n_voxels += 1;
          meansquared<value_type>(output1.value(), output2.value(), sos);
        }
    } else if (use_mask2){
      for (auto i = Loop() (output1, output2, output2mask); i ;++i)
        if (output2mask.value()){
          n_voxels += 1;
          meansquared<value_type>(output1.value(), output2.value(), sos);
        }
    } else {
      for (auto i = Loop() (output1, output2); i ;++i)
        meansquared<value_type>(output1.value(), output2.value(), sos);
    }

  }
  DEBUG ("n_voxels:" + str(n_voxels));
  if (n_voxels==0)
    WARN("number of overlapping voxels is zero");

  if (!nonormalisation)
    sos /= static_cast<value_type>(n_voxels);
  std::cout << str(sos) << std::endl;
}

<commit_msg>mrmetric now also takes 4D images<commit_after>#include "command.h"
#include "image.h"
#include "algo/loop.h"
#include "math/math.h"

#include "image/average_space.h"
#include "interp/linear.h"
#include "interp/nearest.h"
#include "interp/cubic.h"
#include "interp/sinc.h"
#include "filter/reslice.h"

using namespace MR;
using namespace App;

const char* interp_choices[] = { "nearest", "linear", "cubic", "sinc", NULL }; // TODO
const char* space_choices[] = { "voxel", "image1", "image2", "average", NULL };

template <class ValueType>
inline void meansquared (const ValueType& value1,
  const ValueType& value2,
  Eigen::Matrix<ValueType, Eigen::Dynamic, 1>& cost){
  cost.array() += Math::pow2 (value1 - value2);
}

template <class ValueType>
inline void meansquared (const Eigen::Matrix<ValueType,Eigen::Dynamic, 1>& value1,
  const Eigen::Matrix<ValueType,Eigen::Dynamic, 1>& value2,
  Eigen::Matrix<ValueType, Eigen::Dynamic, 1>& cost) {
  cost.array() += (value1 - value2).array().square();
}

// TODO: there must be a better way of doing this?
template <class ImageType1, class ImageType2, class TransformType, class OversampleType, class ValueType>
void reslice(size_t interp, ImageType1& input, ImageType2& output, const TransformType& trafo = Adapter::NoTransform, const OversampleType& oversample = Adapter::AutoOverSample, const ValueType out_of_bounds_value = 0.f){
  switch(interp){
    case 0:
      Filter::reslice<Interp::Nearest> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Nearest");
      break;
    case 1:
      Filter::reslice<Interp::Linear> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Linear");
      break;
    case 2:
      Filter::reslice<Interp::Cubic> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Cubic");
      break;
    case 3:
      Filter::reslice<Interp::Sinc> (input, output, trafo, Adapter::AutoOverSample, out_of_bounds_value);
      DEBUG("Sinc");
      break;
    default:
      throw Exception ("Fixme: interpolation value invalid");
  }
}

void usage ()
{
  AUTHOR = "David Raffelt (david.raffelt@florey.edu.au)";

  DESCRIPTION
  + "computes a dissimilarity metric between two images. Currently only the mean squared difference is implemented";

  ARGUMENTS
  + Argument ("image1", "the first input image.").type_image_in ()
  + Argument ("image2", "the second input image.").type_image_in ();

  OPTIONS
  + Option ("space",
        "voxel (default): per voxel "
        "image1: scanner space of image 1 "
        "image2: scanner space of image 2 "
        "average: scanner space of the average affine transformation of image 1 and 2 ")
    +   Argument ("iteration method").type_choice (space_choices)

    + Option ("interp",
        "set the interpolation method to use when reslicing (choices: nearest, linear, cubic, sinc. Default: cubic).")
    + Argument ("method").type_choice (interp_choices)

    + Option ("mask1", "mask for image 1")
    + Argument ("image").type_image_in ()

    + Option ("mask2", "mask for image 2")
    + Argument ("image").type_image_in ()

    + Option ("nonormalisation",
        "do not normalise the dissimilarity metric to the number of voxels.");

}

typedef double value_type;
typedef Image<bool> MaskType;

void run ()
{
  auto input1 = Image<value_type>::open (argument[0]).with_direct_io (Stride::contiguous_along_axis (3));;
  auto input2 = Image<value_type>::open (argument[1]).with_direct_io (Stride::contiguous_along_axis (3));;

  const size_t dimensions = input1.ndim();
  if (input1.ndim() != input2.ndim())
    throw Exception ("both images have to have the same number of dimensions");
  DEBUG("dimensions: " + str(dimensions));
  if (dimensions > 4) throw Exception ("images have to be 3D or 4D");

  size_t volumes(1);
  if (dimensions == 4)
    volumes = input1.size(3);
    if (input1.size(3) != input2.size(3)){
      throw Exception ("both images have to have the same number of volumes");
    }
  DEBUG("volumes: " + str(volumes));

  int space = 0;  // voxel
  auto opt = get_options ("space");
  if (opt.size())
    space = opt[0][0];

  MaskType mask1;
  bool use_mask1 = get_options ("mask1").size()==1;
  if (use_mask1) {
    mask1 = Image<bool>::open(get_options ("mask1")[0][0]);
    if (mask1.ndim() != 3) throw Exception ("mask has to be 3D");
  }

  MaskType mask2;
  bool use_mask2 = get_options ("mask2").size()==1;
  if (use_mask2){
    mask2 = Image<bool>::open(get_options ("mask2")[0][0]);
    if (mask2.ndim() != 3) throw Exception ("mask has to be 3D");
  }

  bool nonormalisation = false;
  if (get_options ("nonormalisation").size())
    nonormalisation = true;
  ssize_t n_voxels = input1.size(0) * input1.size(1) * input1.size(2);

  value_type out_of_bounds_value = 0.0;

  Eigen::Matrix<value_type, Eigen::Dynamic, 1> sos = Eigen::Matrix<value_type, Eigen::Dynamic, 1>::Zero (volumes);
  if (space==0){
    DEBUG("per-voxel");
    check_dimensions (input1, input2);
    if (use_mask1 or use_mask2)
      n_voxels = 0;
    if (use_mask1 and use_mask2) {
      if (dimensions == 3) {
        for (auto i = Loop() (input1, input2, mask1, mask2); i ;++i)
          if (mask1.value() and mask2.value()){
            ++n_voxels;
            meansquared<value_type>(input1.value(), input2.value(), sos);
          }
      } else { // 4D
        for (auto i = Loop(0, 3) (input1, input2, mask1, mask2); i ;++i) {
          if (mask1.value() and mask2.value()){
            ++n_voxels;
            meansquared<value_type>(input1.row(3), input2.row(3), sos);
          }
        }
      }
    } else if (use_mask1) {
        if (dimensions == 3) {
          for (auto i = Loop() (input1, input2, mask1); i ;++i)
            if (mask1.value()){
              ++n_voxels;
              meansquared<value_type>(input1.value(), input2.value(), sos);
            }
        } else { // 4D
          for (auto i = Loop(0, 3) (input1, input2, mask1); i ;++i) {
            if (mask1.value()){
              ++n_voxels;
              meansquared<value_type>(input1.row(3), input2.row(3), sos);
            }
          }
        }
    } else if (use_mask2){
      if (dimensions == 3) {
          for (auto i = Loop() (input1, input2, mask2); i ;++i)
            if (mask2.value()){
              ++n_voxels;
              meansquared<value_type>(input1.value(), input2.value(), sos);
            }
        } else { // 4D
          for (auto i = Loop(0, 3) (input1, input2, mask2); i ;++i) {
            if (mask2.value()){
              ++n_voxels;
              meansquared<value_type>(input1.row(3), input2.row(3), sos);
            }
          }
        }
    } else {
      for (auto i = Loop() (input1, input2); i ;++i)
        meansquared<value_type>(input1.value(), input2.value(), sos);
    }
  } else {
    DEBUG("scanner space");
    int interp = 2;  // cubic
    opt = get_options ("interp");
    if (opt.size())
      interp = opt[0][0];

    auto output1 = Header::scratch(input1.original_header(),"-").get_image<value_type>();
    auto output2 = Header::scratch(input2.original_header(),"-").get_image<value_type>();

    MaskType output1mask;
    MaskType output2mask;

    if (space == 1){
      DEBUG("image 1");
      output1 = input1;
      output1mask = mask1;
      output2 = Header::scratch(input1.original_header(),"-").get_image<value_type>();
      output2mask = Header::scratch(input1.original_header(),"-").get_image<bool>();
      {
        LogLevelLatch log_level (0);
        reslice(interp,input2, output2, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        if (use_mask2)
          Filter::reslice<Interp::Nearest> (mask2, output2mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
      }
    }

    if (space == 2) {
      DEBUG("image 2");
      output1 = Header::scratch(input2.original_header(),"-").get_image<value_type>();
      output1mask = Header::scratch(input2.original_header(),"-").get_image<bool>();
      output2 = input2;
      output2mask = mask2;
      {
        LogLevelLatch log_level (0);
        reslice(interp, input1, output1, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        if (use_mask1)
          Filter::reslice<Interp::Nearest> (mask1, output1mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
      }
      n_voxels = input2.size(0) * input2.size(1) * input2.size(2);
    }

    if (space == 3) {
      DEBUG("average space");
      std::vector<Header> headers;
      headers.push_back (input1.original_header());
      headers.push_back (input2.original_header());
      default_type template_res = 1.0;
      auto padding = Eigen::Matrix<default_type, 4, 1>(0, 0, 0, 1.0);
      std::vector<Eigen::Transform<double, 3, Eigen::Projective>> transform_header_with;

      auto template_header = compute_minimum_average_header<double,Eigen::Transform<double, 3, Eigen::Projective>>(headers, template_res, padding, transform_header_with);
      template_header.set_ndim(input1.ndim());

      output1 = Image<value_type>::scratch(input1.original_header(),"-");
      output2 = Image<value_type>::scratch(input1.original_header(),"-");
      output1mask = Header::scratch(template_header,"-").get_image<bool>();
      output2mask = Header::scratch(template_header,"-").get_image<bool>();
      {
        LogLevelLatch log_level (0);
        reslice(interp, input1, output1, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        reslice(interp, input2, output2, Adapter::NoTransform, Adapter::AutoOverSample, out_of_bounds_value);
        if (use_mask1)
          Filter::reslice<Interp::Nearest> (mask1, output1mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
        if (use_mask2)
          Filter::reslice<Interp::Nearest> (mask2, output2mask, Adapter::NoTransform, Adapter::AutoOverSample, 0);
      }
      n_voxels = output1.size(0) * output1.size(1) * output1.size(2);
    }

    if (use_mask1 or use_mask2)
      n_voxels = 0;
    if (use_mask1 and use_mask2){
      if (dimensions == 3) {
        for (auto i = Loop() (output1, output2, output1mask, output2mask); i ;++i)
          if (output1mask.value() and output2mask.value()){
            ++n_voxels;
            meansquared<value_type>(output1.value(), output2.value(), sos);
          }
      } else { // 4D
        for (auto i = Loop(0, 3) (output1, output2, output1mask, output2mask); i ;++i) {
          if (output1mask.value() and output2mask.value()){
            ++n_voxels;
            meansquared<value_type>(output1.row(3), output2.row(3), sos);
          }
        }
      }
    } else if (use_mask1){
      if (dimensions == 3) {
        for (auto i = Loop() (output1, output2, output1mask); i ;++i)
          if (output1mask.value()){
            ++n_voxels;
            meansquared<value_type>(output1.value(), output2.value(), sos);
          }
      } else { // 4D
        for (auto i = Loop(0, 3) (output1, output2, output1mask); i ;++i) {
          if (output1mask.value()){
            ++n_voxels;
            meansquared<value_type>(output1.row(3), output2.row(3), sos);
          }
        }
      }
    } else if (use_mask2){
      if (dimensions == 3) {
        for (auto i = Loop() (output1, output2, output2mask); i ;++i)
          if (output2mask.value()){
            ++n_voxels;
            meansquared<value_type>(output1.value(), output2.value(), sos);
          }
      } else { // 4D
        for (auto i = Loop(0, 3) (output1, output2, output2mask); i ;++i) {
          if (output2mask.value()){
            ++n_voxels;
            meansquared<value_type>(output1.row(3), output2.row(3), sos);
          }
        }
      }
    } else {
      if (dimensions == 3) {
        for (auto i = Loop() (output1, output2); i ;++i)
          meansquared<value_type>(output1.value(), output2.value(), sos);
      } else { // 4D
        for (auto i = Loop(0, 3) (output1, output2); i ;++i)
          meansquared<value_type>(output1.row(3), output2.row(3), sos);
      }
    }

  }
  DEBUG ("n_voxels:" + str(n_voxels));
  if (n_voxels==0)
    WARN("number of overlapping voxels is zero");

  if (!nonormalisation)
    sos.array() /= static_cast<value_type>(n_voxels);
  std::cout << str(sos.transpose()) << std::endl;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pgrditem.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 14:20:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SVX_PGRDITEM_HXX
#define _SVX_PGRDITEM_HXX

// include ---------------------------------------------------------------

#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

// class SvxParaGridItem -------------------------------------------------

/*
    [Beschreibung]
    Paragraph snap to grid
*/

class SVX_DLLPUBLIC SvxParaGridItem : public SfxBoolItem
{
public:
    TYPEINFO();

    SvxParaGridItem( const BOOL bSnapToGrid /*= TRUE*/,
                     const USHORT nId  );

    // "pure virtual Methoden" vom SfxPoolItem
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;
    virtual SfxPoolItem*    Create(SvStream &, USHORT) const;
    virtual USHORT          GetVersion( USHORT nFileVersion ) const;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    String &rText, const IntlWrapper * = 0 ) const;
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.5.446); FILE MERGED 2008/04/01 15:49:19 thb 1.5.446.3: #i85898# Stripping all external header guards 2008/04/01 12:46:24 thb 1.5.446.2: #i85898# Stripping all external header guards 2008/03/31 14:17:59 rt 1.5.446.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: pgrditem.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SVX_PGRDITEM_HXX
#define _SVX_PGRDITEM_HXX

// include ---------------------------------------------------------------

#include <svtools/eitem.hxx>
#include "svx/svxdllapi.h"

// class SvxParaGridItem -------------------------------------------------

/*
    [Beschreibung]
    Paragraph snap to grid
*/

class SVX_DLLPUBLIC SvxParaGridItem : public SfxBoolItem
{
public:
    TYPEINFO();

    SvxParaGridItem( const BOOL bSnapToGrid /*= TRUE*/,
                     const USHORT nId  );

    // "pure virtual Methoden" vom SfxPoolItem
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const;
    virtual SfxPoolItem*    Create(SvStream &, USHORT) const;
    virtual USHORT          GetVersion( USHORT nFileVersion ) const;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    String &rText, const IntlWrapper * = 0 ) const;
};

#endif

<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/plugins/gtk_plugin_container_manager.h"

#include <gtk/gtk.h>

#include "app/gfx/gtk_util.h"
#include "base/logging.h"
#include "webkit/glue/plugins/gtk_plugin_container.h"
#include "webkit/glue/webplugin.h"

GtkWidget* GtkPluginContainerManager::CreatePluginContainer(
    gfx::PluginWindowHandle id) {
  DCHECK(host_widget_);
  GtkWidget *widget = gtk_plugin_container_new();
  plugin_window_to_widget_map_.insert(std::make_pair(id, widget));

  // The Realize callback is responsible for adding the plug into the socket.
  // The reason is 2-fold:
  // - the plug can't be added until the socket is realized, but this may not
  // happen until the socket is attached to a top-level window, which isn't the
  // case for background tabs.
  // - when dragging tabs, the socket gets unrealized, which breaks the XEMBED
  // connection. We need to make it again when the tab is reattached, and the
  // socket gets realized again.
  //
  // Note, the RealizeCallback relies on the plugin_window_to_widget_map_ to
  // have the mapping.
  g_signal_connect(G_OBJECT(widget), "realize",
                   G_CALLBACK(RealizeCallback), this);

  // Don't destroy the widget when the plug is removed.
  g_signal_connect(G_OBJECT(widget), "plug-removed",
                   G_CALLBACK(gtk_true), NULL);

  gtk_container_add(GTK_CONTAINER(host_widget_), widget);
  gtk_widget_show(widget);

  return widget;
}

void GtkPluginContainerManager::DestroyPluginContainer(
    gfx::PluginWindowHandle id) {
  DCHECK(host_widget_);
  GtkWidget* widget = MapIDToWidget(id);
  if (widget)
    gtk_widget_destroy(widget);

  plugin_window_to_widget_map_.erase(id);
}

void GtkPluginContainerManager::MovePluginContainer(
    const webkit_glue::WebPluginGeometry& move) {
  DCHECK(host_widget_);
  GtkWidget *widget = MapIDToWidget(move.window);
  if (!widget)
    return;

  DCHECK(!GTK_WIDGET_NO_WINDOW(widget));
  DCHECK(GTK_WIDGET_REALIZED(widget));

  if (!move.visible) {
    gtk_widget_hide(widget);
    return;
  } else {
    gtk_widget_show(widget);
  }

  GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle();
  GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
  gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects);
  gdk_window_shape_combine_region(widget->window, clip_region, 0, 0);
  gdk_region_destroy(clip_region);

  // Update the window position.  Resizing is handled by WebPluginDelegate.
  // TODO(deanm): Verify that we only need to move and not resize.
  // TODO(evanm): we should cache the last shape and position and skip all
  // of this business in the common case where nothing has changed.
  int current_x, current_y;

  // Until the above TODO is resolved, we can grab the last position
  // off of the GtkFixed with a bit of hackery.
  GValue value = {0};
  g_value_init(&value, G_TYPE_INT);
  gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
                                   "x", &value);
  current_x = g_value_get_int(&value);
  gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
                                   "y", &value);
  current_y = g_value_get_int(&value);
  g_value_unset(&value);

  if (move.window_rect.x() != current_x ||
      move.window_rect.y() != current_y) {
    // Calling gtk_fixed_move unnecessarily is a no-no, as it causes the
    // parent window to repaint!
    gtk_fixed_move(GTK_FIXED(host_widget_),
                   widget,
                   move.window_rect.x(),
                   move.window_rect.y());
  }

  gtk_plugin_container_set_size(widget,
                                move.window_rect.width(),
                                move.window_rect.height());
}

GtkWidget* GtkPluginContainerManager::MapIDToWidget(
    gfx::PluginWindowHandle id) {
  PluginWindowToWidgetMap::const_iterator i =
      plugin_window_to_widget_map_.find(id);
  if (i != plugin_window_to_widget_map_.end())
    return i->second;

  LOG(ERROR) << "Request for widget host for unknown window id " << id;

  return NULL;
}

gfx::PluginWindowHandle GtkPluginContainerManager::MapWidgetToID(
     GtkWidget* widget) {
  for (PluginWindowToWidgetMap::const_iterator i =
          plugin_window_to_widget_map_.begin();
       i != plugin_window_to_widget_map_.end(); ++i) {
    if (i->second == widget)
      return i->first;
  }

  LOG(ERROR) << "Request for id for unknown widget";
  return 0;
}

// static
void GtkPluginContainerManager::RealizeCallback(GtkWidget* widget,
                                                void* user_data) {
  GtkPluginContainerManager* plugin_container_manager =
      static_cast<GtkPluginContainerManager*>(user_data);

  gfx::PluginWindowHandle id = plugin_container_manager->MapWidgetToID(widget);
  if (id)
    gtk_socket_add_id(GTK_SOCKET(widget), id);
}
<commit_msg>linux: obey move.rects_valid in WebPluginGeometry<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/plugins/gtk_plugin_container_manager.h"

#include <gtk/gtk.h>

#include "app/gfx/gtk_util.h"
#include "base/logging.h"
#include "webkit/glue/plugins/gtk_plugin_container.h"
#include "webkit/glue/webplugin.h"

GtkWidget* GtkPluginContainerManager::CreatePluginContainer(
    gfx::PluginWindowHandle id) {
  DCHECK(host_widget_);
  GtkWidget *widget = gtk_plugin_container_new();
  plugin_window_to_widget_map_.insert(std::make_pair(id, widget));

  // The Realize callback is responsible for adding the plug into the socket.
  // The reason is 2-fold:
  // - the plug can't be added until the socket is realized, but this may not
  // happen until the socket is attached to a top-level window, which isn't the
  // case for background tabs.
  // - when dragging tabs, the socket gets unrealized, which breaks the XEMBED
  // connection. We need to make it again when the tab is reattached, and the
  // socket gets realized again.
  //
  // Note, the RealizeCallback relies on the plugin_window_to_widget_map_ to
  // have the mapping.
  g_signal_connect(G_OBJECT(widget), "realize",
                   G_CALLBACK(RealizeCallback), this);

  // Don't destroy the widget when the plug is removed.
  g_signal_connect(G_OBJECT(widget), "plug-removed",
                   G_CALLBACK(gtk_true), NULL);

  gtk_container_add(GTK_CONTAINER(host_widget_), widget);
  gtk_widget_show(widget);

  return widget;
}

void GtkPluginContainerManager::DestroyPluginContainer(
    gfx::PluginWindowHandle id) {
  DCHECK(host_widget_);
  GtkWidget* widget = MapIDToWidget(id);
  if (widget)
    gtk_widget_destroy(widget);

  plugin_window_to_widget_map_.erase(id);
}

void GtkPluginContainerManager::MovePluginContainer(
    const webkit_glue::WebPluginGeometry& move) {
  DCHECK(host_widget_);
  GtkWidget *widget = MapIDToWidget(move.window);
  if (!widget)
    return;

  DCHECK(!GTK_WIDGET_NO_WINDOW(widget));

  if (!move.visible) {
    gtk_widget_hide(widget);
    return;
  }

  DCHECK(GTK_WIDGET_REALIZED(widget));
  gtk_widget_show(widget);

  if (!move.rects_valid)
    return;

  GdkRectangle clip_rect = move.clip_rect.ToGdkRectangle();
  GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
  gfx::SubtractRectanglesFromRegion(clip_region, move.cutout_rects);
  gdk_window_shape_combine_region(widget->window, clip_region, 0, 0);
  gdk_region_destroy(clip_region);

  // Update the window position.  Resizing is handled by WebPluginDelegate.
  // TODO(deanm): Verify that we only need to move and not resize.
  // TODO(evanm): we should cache the last shape and position and skip all
  // of this business in the common case where nothing has changed.
  int current_x, current_y;

  // Until the above TODO is resolved, we can grab the last position
  // off of the GtkFixed with a bit of hackery.
  GValue value = {0};
  g_value_init(&value, G_TYPE_INT);
  gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
                                   "x", &value);
  current_x = g_value_get_int(&value);
  gtk_container_child_get_property(GTK_CONTAINER(host_widget_), widget,
                                   "y", &value);
  current_y = g_value_get_int(&value);
  g_value_unset(&value);

  if (move.window_rect.x() != current_x ||
      move.window_rect.y() != current_y) {
    // Calling gtk_fixed_move unnecessarily is a no-no, as it causes the
    // parent window to repaint!
    gtk_fixed_move(GTK_FIXED(host_widget_),
                   widget,
                   move.window_rect.x(),
                   move.window_rect.y());
  }

  gtk_plugin_container_set_size(widget,
                                move.window_rect.width(),
                                move.window_rect.height());
}

GtkWidget* GtkPluginContainerManager::MapIDToWidget(
    gfx::PluginWindowHandle id) {
  PluginWindowToWidgetMap::const_iterator i =
      plugin_window_to_widget_map_.find(id);
  if (i != plugin_window_to_widget_map_.end())
    return i->second;

  LOG(ERROR) << "Request for widget host for unknown window id " << id;

  return NULL;
}

gfx::PluginWindowHandle GtkPluginContainerManager::MapWidgetToID(
     GtkWidget* widget) {
  for (PluginWindowToWidgetMap::const_iterator i =
          plugin_window_to_widget_map_.begin();
       i != plugin_window_to_widget_map_.end(); ++i) {
    if (i->second == widget)
      return i->first;
  }

  LOG(ERROR) << "Request for id for unknown widget";
  return 0;
}

// static
void GtkPluginContainerManager::RealizeCallback(GtkWidget* widget,
                                                void* user_data) {
  GtkPluginContainerManager* plugin_container_manager =
      static_cast<GtkPluginContainerManager*>(user_data);

  gfx::PluginWindowHandle id = plugin_container_manager->MapWidgetToID(widget);
  if (id)
    gtk_socket_add_id(GTK_SOCKET(widget), id);
}
<|endoftext|>