<commit_before>#include <osgUtil/DelaunayTriangulator>

#include <osg/GL>
#include <osg/Vec3>
#include <osg/Array>
#include <osg/Notify>

#include <algorithm>
#include <list>
#include <set>

namespace osgUtil
{

//////////////////////////////////////////////////////////////////////////////////////
// MISC MATH FUNCTIONS

// Compute the circumcircle of a triangle (only x and y coordinates are used),
// return (Cx, Cy, r^2)

inline osg::Vec3 compute_circumcircle(
    const osg::Vec3 &a,
    const osg::Vec3 &b,
    const osg::Vec3 &c)
{
    float D =
        (a.x() - c.x()) * (b.y() - c.y()) -
        (b.x() - c.x()) * (a.y() - c.y());

    float cx =
        (((a.x() - c.x()) * (a.x() + c.x()) +
        (a.y() - c.y()) * (a.y() + c.y())) / 2 * (b.y() - c.y()) -
        ((b.x() - c.x()) * (b.x() + c.x()) +
        (b.y() - c.y()) * (b.y() + c.y())) / 2 * (a.y() - c.y())) / D;

    float cy =
        (((b.x() - c.x()) * (b.x() + c.x()) +
        (b.y() - c.y()) * (b.y() + c.y())) / 2 * (a.x() - c.x()) -
        ((a.x() - c.x()) * (a.x() + c.x()) +
        (a.y() - c.y()) * (a.y() + c.y())) / 2 * (b.x() - c.x())) / D;

    float r2 = (c.x() - cx) * (c.x() - cx) + (c.y() - cy) * (c.y() - cy);

    return osg::Vec3(cx, cy, r2);
}

// Test whether a point (only the x and y coordinates are used) lies inside
// a circle; the circle is passed as a vector: (Cx, Cy, r^2).

inline bool point_in_circle(const osg::Vec3 &point, const osg::Vec3 &circle)
{
    float r2 =
        (point.x() - circle.x()) * (point.x() - circle.x()) +
        (point.y() - circle.y()) * (point.y() - circle.y());
    return r2 <= circle.z();
}

//
//////////////////////////////////////////////////////////////////////////////////////

// data type for vertex indices
typedef GLuint Vertex_index;

// CLASS: Edge
// This class describes an edge of a triangle (it stores vertex indices to the two
// endpoints).

class Edge {
public:

    // Comparison object (for sorting)
    struct Less {
        inline bool operator()(const Edge &e1, const Edge &e2) const
        {
            if (e1.ibs() < e2.ibs()) return true;
            if (e1.ibs() > e2.ibs()) return false;
            if (e1.ies() < e2.ies()) return true;
            return false;
        }
    };

    Edge() {}
    Edge(Vertex_index ib, Vertex_index ie) : ib_(ib), ie_(ie), ibs_(osg::minimum(ib, ie)), ies_(osg::maximum(ib, ie)), duplicate_(false) {}

    // first endpoint
    inline Vertex_index ib() const { return ib_; }

    // second endpoint
    inline Vertex_index ie() const { return ie_; }

    // first sorted endpoint
    inline Vertex_index ibs() const { return ibs_; }

    // second sorted endpoint
    inline Vertex_index ies() const { return ies_; }

    // get the "duplicate" flag
    inline bool get_duplicate() const { return duplicate_; }

    // set the "duplicate" flag
    inline void set_duplicate(bool v) { duplicate_ = v; }

private:
    Vertex_index ib_, ie_;
    Vertex_index ibs_, ies_;
    bool duplicate_;
};

// CLASS: Triangle

class Triangle {
public:
    Triangle(Vertex_index a, Vertex_index b, Vertex_index c, osg::Vec3Array *points)
        :    a_(a),
            b_(b),
            c_(c),
            cc_(compute_circumcircle((*points)[a_], (*points)[b_], (*points)[c_]))
    {
        edge_[0] = Edge(a_, b_);
        edge_[1] = Edge(b_, c_);
        edge_[2] = Edge(c_, a_);
    }

    inline Vertex_index a() const { return a_; }
    inline Vertex_index b() const { return b_; }
    inline Vertex_index c() const { return c_; }

    inline const Edge &get_edge(int idx) const { return edge_[idx];    }
    inline const osg::Vec3 &get_circumcircle() const { return cc_; }

    inline osg::Vec3 compute_normal(osg::Vec3Array *points) const
    {
        osg::Vec3 N = ((*points)[b_] - (*points)[a_]) ^ ((*points)[c_] - (*points)[a_]);
        return N / N.length();
    }

private:
    Vertex_index a_;
    Vertex_index b_;
    Vertex_index c_;
    osg::Vec3 cc_;
    Edge edge_[3];
};

// comparison function for sorting sample points by the X coordinate
bool Sample_point_compare(const osg::Vec3 &p1, const osg::Vec3 &p2)
{
    return p1.x() < p2.x();
}

// container types
typedef std::set<Edge, Edge::Less> Edge_set;
typedef std::list<Triangle> Triangle_list;

DelaunayTriangulator::DelaunayTriangulator():
    osg::Referenced()
{
}

DelaunayTriangulator::DelaunayTriangulator(osg::Vec3Array *points, osg::Vec3Array *normals):
    osg::Referenced(),
    points_(points),
    normals_(normals)
{
}

DelaunayTriangulator::DelaunayTriangulator(const DelaunayTriangulator &copy, const osg::CopyOp &copyop):
    osg::Referenced(copy),
    points_(static_cast<osg::Vec3Array *>(copyop(copy.points_.get()))),
    normals_(static_cast<osg::Vec3Array *>(copyop(copy.normals_.get()))),
    prim_tris_(static_cast<osg::DrawElementsUInt *>(copyop(copy.prim_tris_.get())))
{
}

DelaunayTriangulator::~DelaunayTriangulator()
{
}

bool DelaunayTriangulator::triangulate()
{
    // check validity of input array
    if (!points_.valid()) {
        osg::notify(osg::WARN) << "Warning: DelaunayTriangulator::triangulate(): invalid sample point array" << std::endl;
        return false;
    }

    osg::Vec3Array *points = points_.get();

    if (points->size() < 1) {
        osg::notify(osg::WARN) << "Warning: DelaunayTriangulator::triangulate(): too few sample points" << std::endl;
        return false;
    }

    // initialize storage structures
    Triangle_list triangles;
    Triangle_list discarded_tris;

    // pre-sort sample points
    osg::notify(osg::INFO) << "DelaunayTriangulator: pre-sorting sample points\n";
    std::sort(points->begin(), points->end(), Sample_point_compare);

    // set the last valid index for the point list
    GLuint last_valid_index = points->size() - 1;

    // find the minimum and maximum x values in the point list
    float minx = (*points)[0].x();
    float maxx = (*points)[last_valid_index].x();

    // find the minimum and maximum x values in the point list
    float miny = (*points)[0].y();
    float maxy = miny;

    osg::notify(osg::INFO) << "DelaunayTriangulator: finding minimum and maximum Y values\n";
    osg::Vec3Array::const_iterator mmi;
    for (mmi=points->begin(); mmi!=points->end(); ++mmi) {
        if (mmi->y() < miny) miny = mmi->y();
        if (mmi->y() > maxy) maxy = mmi->y();
    }

    // add supertriangle vertices to the point list
    points->push_back(osg::Vec3(minx - (maxx - minx), miny, 0));
    points->push_back(osg::Vec3(maxx, miny, 0));
    points->push_back(osg::Vec3(maxx, maxy + (maxy - miny), 0));

    // add supertriangle to triangle list
    triangles.push_back(Triangle(last_valid_index+1, last_valid_index+2, last_valid_index+3, points));

    // begin triangulation
    GLuint pidx = 0;
    osg::Vec3Array::const_iterator i;

    osg::notify(osg::INFO) << "DelaunayTriangulator: triangulating vertex grid (" << (points->size()-3) <<" points)\n";

    for (i=points->begin(); i!=points->end(); ++i, ++pidx) {

        // don't process supertriangle vertices
        if (pidx > last_valid_index) break;

        Edge_set edges;

        // iterate through triangles
        Triangle_list::iterator j, next_j;
        for (j=triangles.begin(); j!=triangles.end(); j = next_j) {

            next_j = j;
            ++next_j;

            // compute the circumcircle
            osg::Vec3 cc = j->get_circumcircle();

            // OPTIMIZATION: since points are pre-sorted by the X component,
            // check whether we can discard this triangle for future operations
            float xdist = i->x() - cc.x();
            if ((xdist * xdist) > cc.z() && i->x() > cc.x()) {
                discarded_tris.push_back(*j);
                triangles.erase(j);
            } else {

                // if the point lies in the triangle's circumcircle then add
                // its edges to the edge list and remove the triangle
                if (point_in_circle(*i, cc))
                {
                    for (int ei=0; ei<3; ++ei)
                    {
                        std::pair<Edge_set::iterator, bool> result = edges.insert(j->get_edge(ei));
                        if (!result.second)
                        {
                            // cast away constness of a set element, which is
                            // safe in this case since the set_duplicate is
                            // not used as part of the Less operator.
                            Edge& edge = const_cast<Edge&>(*(result.first));
                            edge.set_duplicate(true);
                        }
                    }
                    triangles.erase(j);
                }
            }
        }

        // remove duplicate edges and add new triangles
        Edge_set::iterator ci;
        for (ci=edges.begin(); ci!=edges.end(); ++ci) {
            if (!ci->get_duplicate()) {
                triangles.push_back(Triangle(pidx, ci->ib(), ci->ie(), points));
            }
        }
    }

    osg::notify(osg::INFO) << "DelaunayTriangulator: finalizing and cleaning up structures\n";

    // remove supertriangle vertices
    points->pop_back();
    points->pop_back();
    points->pop_back();

    // rejoin the two triangle lists
    triangles.insert(triangles.begin(), discarded_tris.begin(), discarded_tris.end());

    // initialize index storage vector
    std::vector<GLuint> pt_indices;
    pt_indices.reserve(triangles.size() * 3);

    // build osg primitive
    osg::notify(osg::INFO) << "DelaunayTriangulator: building primitive(s)\n";
    Triangle_list::const_iterator ti;
    for (ti=triangles.begin(); ti!=triangles.end(); ++ti) {

        // don't add this triangle to the primitive if it shares any vertex with
        // the supertriangle
        if (ti->a() <= last_valid_index && ti->b() <= last_valid_index && ti->c() <= last_valid_index) {

            if (normals_.valid()) {
                (normals_.get())->push_back(ti->compute_normal(points));
            }

            pt_indices.push_back(ti->a());
            pt_indices.push_back(ti->b());
            pt_indices.push_back(ti->c());
        }
    }

    prim_tris_ = new osg::DrawElementsUInt(GL_TRIANGLES, pt_indices.size(), &(pt_indices.front()));

    osg::notify(osg::INFO) << "DelaunayTriangulator: process done, " << (pt_indices.size() / 3) << " triangles created\n";

    return true;
}

}
<commit_msg>From David Spilling, fixed the incircle test so it handles colinear points.<commit_after>#include <osgUtil/DelaunayTriangulator>

#include <osg/GL>
#include <osg/Vec3>
#include <osg/Array>
#include <osg/Notify>

#include <algorithm>
#include <list>
#include <set>

namespace osgUtil
{

//////////////////////////////////////////////////////////////////////////////////////
// MISC MATH FUNCTIONS

// Compute the circumcircle of a triangle (only x and y coordinates are used),
// return (Cx, Cy, r^2)
inline osg::Vec3 compute_circumcircle(
    const osg::Vec3 &a,
    const osg::Vec3 &b,
    const osg::Vec3 &c)
{
    float D =
        (a.x() - c.x()) * (b.y() - c.y()) -
        (b.x() - c.x()) * (a.y() - c.y());

    float cx, cy, r2;

    if(D==0.0)
    {
        // (Nearly) degenerate condition - either two of the points are equal (which we discount)
        // or the three points are colinear. In this case we just determine the average of
        // the three points as the centre for correctness, but squirt out a zero radius.
        // This method will produce a triangulation with zero area, so we have to check later
        cx = (a.x()+b.x()+c.x())/3.0;
        cy = (a.y()+b.y()+c.y())/3.0;
        r2 = 0.0;
    }
    else
    {
        cx =
        (((a.x() - c.x()) * (a.x() + c.x()) +
        (a.y() - c.y()) * (a.y() + c.y())) / 2 * (b.y() - c.y()) -
        ((b.x() - c.x()) * (b.x() + c.x()) +
        (b.y() - c.y()) * (b.y() + c.y())) / 2 * (a.y() - c.y())) / D;

        cy =
        (((b.x() - c.x()) * (b.x() + c.x()) +
        (b.y() - c.y()) * (b.y() + c.y())) / 2 * (a.x() - c.x()) -
        ((a.x() - c.x()) * (a.x() + c.x()) +
        (a.y() - c.y()) * (a.y() + c.y())) / 2 * (b.x() - c.x())) / D;

        r2 = (c.x() - cx) * (c.x() - cx) + (c.y() - cy) * (c.y() - cy);
    }
    return osg::Vec3(cx, cy, r2);
}

// Test whether a point (only the x and y coordinates are used) lies inside
// a circle; the circle is passed as a vector: (Cx, Cy, r^2).

inline bool point_in_circle(const osg::Vec3 &point, const osg::Vec3 &circle)
{
    float r2 =
        (point.x() - circle.x()) * (point.x() - circle.x()) +
        (point.y() - circle.y()) * (point.y() - circle.y());
    return r2 <= circle.z();
}

//
//////////////////////////////////////////////////////////////////////////////////////

// data type for vertex indices
typedef GLuint Vertex_index;

// CLASS: Edge
// This class describes an edge of a triangle (it stores vertex indices to the two
// endpoints).

class Edge {
public:

    // Comparison object (for sorting)
    struct Less {
        inline bool operator()(const Edge &e1, const Edge &e2) const
        {
            if (e1.ibs() < e2.ibs()) return true;
            if (e1.ibs() > e2.ibs()) return false;
            if (e1.ies() < e2.ies()) return true;
            return false;
        }
    };

    Edge() {}
    Edge(Vertex_index ib, Vertex_index ie) : ib_(ib), ie_(ie), ibs_(osg::minimum(ib, ie)), ies_(osg::maximum(ib, ie)), duplicate_(false) {}

    // first endpoint
    inline Vertex_index ib() const { return ib_; }

    // second endpoint
    inline Vertex_index ie() const { return ie_; }

    // first sorted endpoint
    inline Vertex_index ibs() const { return ibs_; }

    // second sorted endpoint
    inline Vertex_index ies() const { return ies_; }

    // get the "duplicate" flag
    inline bool get_duplicate() const { return duplicate_; }

    // set the "duplicate" flag
    inline void set_duplicate(bool v) { duplicate_ = v; }

private:
    Vertex_index ib_, ie_;
    Vertex_index ibs_, ies_;
    bool duplicate_;
};

// CLASS: Triangle

class Triangle {
public:
    Triangle(Vertex_index a, Vertex_index b, Vertex_index c, osg::Vec3Array *points)
        :    a_(a),
            b_(b),
            c_(c),
            cc_(compute_circumcircle((*points)[a_], (*points)[b_], (*points)[c_]))
    {
        edge_[0] = Edge(a_, b_);
        edge_[1] = Edge(b_, c_);
        edge_[2] = Edge(c_, a_);
    }

    inline Vertex_index a() const { return a_; }
    inline Vertex_index b() const { return b_; }
    inline Vertex_index c() const { return c_; }

    inline const Edge &get_edge(int idx) const { return edge_[idx];    }
    inline const osg::Vec3 &get_circumcircle() const { return cc_; }

    inline osg::Vec3 compute_normal(osg::Vec3Array *points) const
    {
        osg::Vec3 N = ((*points)[b_] - (*points)[a_]) ^ ((*points)[c_] - (*points)[a_]);
        return N / N.length();
    }

private:
    Vertex_index a_;
    Vertex_index b_;
    Vertex_index c_;
    osg::Vec3 cc_;
    Edge edge_[3];
};

// comparison function for sorting sample points by the X coordinate
bool Sample_point_compare(const osg::Vec3 &p1, const osg::Vec3 &p2)
{
    return p1.x() < p2.x();
}

// container types
typedef std::set<Edge, Edge::Less> Edge_set;
typedef std::list<Triangle> Triangle_list;

DelaunayTriangulator::DelaunayTriangulator():
    osg::Referenced()
{
}

DelaunayTriangulator::DelaunayTriangulator(osg::Vec3Array *points, osg::Vec3Array *normals):
    osg::Referenced(),
    points_(points),
    normals_(normals)
{
}

DelaunayTriangulator::DelaunayTriangulator(const DelaunayTriangulator &copy, const osg::CopyOp &copyop):
    osg::Referenced(copy),
    points_(static_cast<osg::Vec3Array *>(copyop(copy.points_.get()))),
    normals_(static_cast<osg::Vec3Array *>(copyop(copy.normals_.get()))),
    prim_tris_(static_cast<osg::DrawElementsUInt *>(copyop(copy.prim_tris_.get())))
{
}

DelaunayTriangulator::~DelaunayTriangulator()
{
}

bool DelaunayTriangulator::triangulate()
{
    // check validity of input array
    if (!points_.valid()) {
        osg::notify(osg::WARN) << "Warning: DelaunayTriangulator::triangulate(): invalid sample point array" << std::endl;
        return false;
    }

    osg::Vec3Array *points = points_.get();

    if (points->size() < 1) {
        osg::notify(osg::WARN) << "Warning: DelaunayTriangulator::triangulate(): too few sample points" << std::endl;
        return false;
    }

    // initialize storage structures
    Triangle_list triangles;
    Triangle_list discarded_tris;

    // pre-sort sample points
    osg::notify(osg::INFO) << "DelaunayTriangulator: pre-sorting sample points\n";
    std::sort(points->begin(), points->end(), Sample_point_compare);

    // set the last valid index for the point list
    GLuint last_valid_index = points->size() - 1;

    // find the minimum and maximum x values in the point list
    float minx = (*points)[0].x();
    float maxx = (*points)[last_valid_index].x();

    // find the minimum and maximum x values in the point list
    float miny = (*points)[0].y();
    float maxy = miny;

    osg::notify(osg::INFO) << "DelaunayTriangulator: finding minimum and maximum Y values\n";
    osg::Vec3Array::const_iterator mmi;
    for (mmi=points->begin(); mmi!=points->end(); ++mmi) {
        if (mmi->y() < miny) miny = mmi->y();
        if (mmi->y() > maxy) maxy = mmi->y();
    }

    // add supertriangle vertices to the point list
    points->push_back(osg::Vec3(minx - (maxx - minx), miny, 0));
    points->push_back(osg::Vec3(maxx, miny, 0));
    points->push_back(osg::Vec3(maxx, maxy + (maxy - miny), 0));

    // add supertriangle to triangle list
    triangles.push_back(Triangle(last_valid_index+1, last_valid_index+2, last_valid_index+3, points));

    // begin triangulation
    GLuint pidx = 0;
    osg::Vec3Array::const_iterator i;

    osg::notify(osg::INFO) << "DelaunayTriangulator: triangulating vertex grid (" << (points->size()-3) <<" points)\n";

    for (i=points->begin(); i!=points->end(); ++i, ++pidx) {

        // don't process supertriangle vertices
        if (pidx > last_valid_index) break;

        Edge_set edges;

        // iterate through triangles
        Triangle_list::iterator j, next_j;
        for (j=triangles.begin(); j!=triangles.end(); j = next_j) {

            next_j = j;
            ++next_j;

            // compute the circumcircle
            osg::Vec3 cc = j->get_circumcircle();

            // OPTIMIZATION: since points are pre-sorted by the X component,
            // check whether we can discard this triangle for future operations
            float xdist = i->x() - cc.x();
            if ((xdist * xdist) > cc.z() && i->x() > cc.x()) {
                discarded_tris.push_back(*j);
                triangles.erase(j);
            } else {

                // if the point lies in the triangle's circumcircle then add
                // its edges to the edge list and remove the triangle
                if (point_in_circle(*i, cc))
                {
                    for (int ei=0; ei<3; ++ei)
                    {
                        std::pair<Edge_set::iterator, bool> result = edges.insert(j->get_edge(ei));
                        if (!result.second)
                        {
                            // cast away constness of a set element, which is
                            // safe in this case since the set_duplicate is
                            // not used as part of the Less operator.
                            Edge& edge = const_cast<Edge&>(*(result.first));
                            edge.set_duplicate(true);
                        }
                    }
                    triangles.erase(j);
                }
            }
        }

        // remove duplicate edges and add new triangles
        Edge_set::iterator ci;
        for (ci=edges.begin(); ci!=edges.end(); ++ci) {
            if (!ci->get_duplicate()) {
                triangles.push_back(Triangle(pidx, ci->ib(), ci->ie(), points));
            }
        }
    }

    osg::notify(osg::INFO) << "DelaunayTriangulator: finalizing and cleaning up structures\n";

    // remove supertriangle vertices
    points->pop_back();
    points->pop_back();
    points->pop_back();

    // rejoin the two triangle lists
    triangles.insert(triangles.begin(), discarded_tris.begin(), discarded_tris.end());

    // initialize index storage vector
    std::vector<GLuint> pt_indices;
    pt_indices.reserve(triangles.size() * 3);

    // build osg primitive
    osg::notify(osg::INFO) << "DelaunayTriangulator: building primitive(s)\n";
    Triangle_list::const_iterator ti;
    for (ti=triangles.begin(); ti!=triangles.end(); ++ti) {

        // don't add this triangle to the primitive if it shares any vertex with
        // the supertriangle
          // Also don't add degenerate (zero radius) triangles
        if (ti->a() <= last_valid_index && ti->b() <= last_valid_index && ti->c() <= last_valid_index && ti->get_circumcircle().z()>0.0) {

            if (normals_.valid()) {
                (normals_.get())->push_back(ti->compute_normal(points));
            }

            pt_indices.push_back(ti->a());
            pt_indices.push_back(ti->b());
            pt_indices.push_back(ti->c());
        }
    }

    prim_tris_ = new osg::DrawElementsUInt(GL_TRIANGLES, pt_indices.size(), &(pt_indices.front()));

    osg::notify(osg::INFO) << "DelaunayTriangulator: process done, " << (pt_indices.size() / 3) << " triangles created\n";

    return true;
}

}
<|endoftext|>


<commit_before>
#include "TStopwatch.h"
#include "TUnuran.h"

#include "TH1.h"

#include "TRandom.h"
#include "TSystem.h"
//#include "TApplication.h"
#include "TVirtualFitter.h"
#include "Math/ProbFunc.h"

#include <iostream>

using std::cout;
using std::endl;

void unuranSimple() {

   // simple test of unuran

   TUnuran unr;
   if (! unr.Init( "normal()", "method=arou") ) {
      cout << "Error initializing unuran" << endl;
      return;
   }

   int n = 1000000;
   TStopwatch w;
   w.Start();

   for (int i = 0; i < n; ++i)
      unr.Sample();

   w.Stop();
   cout << "Time using Unuran =\t\t " << w.CpuTime() << endl;

   w.Start();
   for (int i = 0; i < n; ++i)
      gRandom->Gaus(0,1);

   w.Stop();
   cout << "Time using TRandom::Gaus  =\t " << w.CpuTime() << endl;

   // test the quality by looking at the cdf

   TH1D * h1 = new TH1D("h1","cdf on the data ",100,0,1);
   for (int i = 0; i < n; ++i) {
      double x = unr.Sample();
      // x = gRandom->Gaus(0,1);
      h1->Fill( ROOT::Math::normal_quant( x , 1.0) );
   }
//    gSystem->Load("libMinuit2");
//    TVirtualFitter::SetDefaultFitter("Minuit2");
   std::cout << "Result of fitting a cdf to a constant function : " << std::endl;
   h1->Fit("pol0","Q");
   TF1 * f = (TF1*)gROOT->GetFunction("pol0");
   std::cout << "Fit chi2 = " << f->GetChisquare() << " ndf = " << f->GetNDF() << std::endl;
   std::cout << "Fit Prob = " << f->GetProb() << std::endl;

   h1->Draw();

}

#ifndef __CINT__
int main(int /* argc */, char  **  /* argv */)
{
//   TApplication theApp("App", &argc, argv);
   unuranSimple();
//   theApp.Run();
   return 0;
}
#endif

<commit_msg>fix problem in finding the TFitter on Windows by setting it explicitly<commit_after>
#include "TStopwatch.h"
#include "TUnuran.h"

#include "TH1.h"

#include "TRandom.h"
#include "TSystem.h"
//#include "TApplication.h"
//#include "TRint.h"
#include "TVirtualFitter.h"
#include "TFitter.h"
#include "Math/ProbFunc.h"

#include <iostream>

using std::cout;
using std::endl;

void unuranSimple() {

   // simple test of unuran

   TUnuran unr;
   if (! unr.Init( "normal()", "method=arou") ) {
      cout << "Error initializing unuran" << endl;
      return;
   }

   int n = 1000000;
   TStopwatch w;
   w.Start();

   for (int i = 0; i < n; ++i)
      unr.Sample();

   w.Stop();
   cout << "Time using Unuran =\t\t " << w.CpuTime() << endl;

   w.Start();
   for (int i = 0; i < n; ++i)
      gRandom->Gaus(0,1);

   w.Stop();
   cout << "Time using TRandom::Gaus  =\t " << w.CpuTime() << endl;

   // test the quality by looking at the cdf

   TH1D * h1 = new TH1D("h1","cdf on the data ",100,0,1);
   for (int i = 0; i < n; ++i) {
      double x = unr.Sample();
      // x = gRandom->Gaus(0,1);
      h1->Fill( ROOT::Math::normal_quant( x , 1.0) );
   }
//    gSystem->Load("libMinuit2");
//    TVirtualFitter::SetDefaultFitter("Minuit2");
   std::cout << "Result of fitting a cdf to a constant function : " << std::endl;
   // need TRint();
   TFitter * fitter = new TFitter();
   TVirtualFitter::SetFitter(fitter);
   h1->Fit("pol0","Q");
   TF1 * f = (TF1*)gROOT->GetFunction("pol0");
   std::cout << "Fit chi2 = " << f->GetChisquare() << " ndf = " << f->GetNDF() << std::endl;
   std::cout << "Fit Prob = " << f->GetProb() << std::endl;

   h1->Draw();

   //delete fitter;

}

#ifndef __CINT__
int main()
{
//   TApplication theApp("App", &argc, argv);
  //TRint theApp("TRint",&argc, argv);
  //theApp.Run();
   unuranSimple();
   return 0;
}
#endif

<|endoftext|>


<commit_before>#ifdef _WIN32

#include <pd_backend.h>
#include <assert.h>
#include <stdio.h>
#include <Dbgeng.h>
#include <string>

struct DbgEngPlugin
{
	PDDebugState state = PDDebugState_noTarget;
	bool hasValidTarget = false;

	std::string targetName;

	IDebugClient* debugClient = nullptr;
	IDebugControl* debugControl = nullptr;
};

void onRun(DbgEngPlugin* plugin)
{

}

void onStop(DbgEngPlugin* plugin)
{

}

static void onBreak(DbgEngPlugin* plugin)
{

}

static void onStep(DbgEngPlugin* plugin)
{

}

static void onStepOver(DbgEngPlugin* plugin)
{

}

static void onStepOut(DbgEngPlugin* plugin)
{

}

static void doAction(DbgEngPlugin* plugin, PDAction action)
{
	switch (action)
	{
	case PDAction_stop: onStop(plugin); break;
	case PDAction_break: onBreak(plugin); break;
	case PDAction_run: onRun(plugin); break;
	case PDAction_step: onStep(plugin); break;
	case PDAction_stepOut: onStepOut(plugin); break;
	case PDAction_stepOver: onStepOver(plugin); break;
	}
}

static void setExceptionLocation(DbgEngPlugin* plugin, PDWriter* writer)
{

}

static void setCallstack(DbgEngPlugin* plugin, PDWriter* writer)
{

}

static void setExecutable(DbgEngPlugin* plugin, PDReader* reader)
{
	const char* filename = 0;

	PDRead_findString(reader, &filename, "filename", 0);

	if (!filename)
	{
		printf("Unable to find filename which is required when starting a LLDB debug session\n");
		return;
	}

	printf("found filename \"%s\"\n", filename);

	plugin->targetName = filename;

	HRESULT hr = plugin->debugClient->CreateProcess(0, PSTR(filename), DEBUG_PROCESS);
	assert(SUCCEEDED(hr));

	printf("Valid target %s\n", filename);
}

static void setLocals(DbgEngPlugin* plugin, PDWriter* writer)
{

}

static void setBreakpoint(DbgEngPlugin* plugin, PDReader* reader, PDWriter* writer)
{

}

static void eventAction(DbgEngPlugin* plugin, PDReader* reader)
{
	uint32_t action = 0;

	printf("DbgEngPlugin; %d\n", (PDRead_findU32(reader, &action, "action", 0) & 0xff) >> 8);
	printf("DbgEngPlugin: got action (from event) %d\n", action);

	doAction(plugin, (PDAction)action);
}

static void processEvents(DbgEngPlugin* plugin, PDReader* reader, PDWriter* writer)
{
	PDEventType event;

	while ((event = (PDEventType)PDRead_getEvent(reader)))
	{
		switch (event)
		{
		case PDEventType_getExceptionLocation: setExceptionLocation(plugin, writer); break;
		case PDEventType_getCallstack: setCallstack(plugin, writer); break;
		case PDEventType_setExecutable: setExecutable(plugin, reader); break;
		case PDEventType_getLocals: setLocals(plugin, writer); break;
		case PDEventType_setBreakpoint: setBreakpoint(plugin, reader, writer); break;
		case PDEventType_action: eventAction(plugin, reader); break;
		}
	}
}

void* createInstance(ServiceFunc* serviceFunc)
{
	DbgEngPlugin* plugin = new DbgEngPlugin;

	HRESULT hr = DebugCreate(__uuidof(IDebugClient), (void**)&plugin->debugClient);
	assert(SUCCEEDED(hr));

	hr = plugin->debugClient->QueryInterface(__uuidof(IDebugControl), (void**)&plugin->debugControl);
	assert(SUCCEEDED(hr));

	return plugin;
}

void destroyInstance(void* userData)
{
	DbgEngPlugin* plugin = reinterpret_cast<DbgEngPlugin*>(userData);

	if (plugin->debugControl)
	{
		plugin->debugControl->Release();
		plugin->debugControl = nullptr;
	}

	if (plugin->debugClient)
	{
		plugin->debugClient->Release();
		plugin->debugClient = nullptr;
	}

	delete plugin;
}

static PDDebugState update(void* userData, PDAction action, PDReader* reader, PDWriter* writer)
{
	DbgEngPlugin* plugin = reinterpret_cast<DbgEngPlugin*>(userData);

	processEvents(plugin, reader, writer);

	doAction(plugin, action);

	/*
	if (plugin->state == PDDebugState_running)
		updateDbgEngEvent(plugin, writer);
	*/

	return plugin->state;
}

static PDBackendPlugin plugin =
{
	"Microsoft Debugger Engine",
	createInstance,
	destroyInstance,
	update,
};

extern "C" PD_EXPORT void InitPlugin(RegisterPlugin* registerPlugin, void* privateData)
{
	registerPlugin(PD_BACKEND_API_VERSION, &plugin, privateData);
}

#endif
<commit_msg>Added stubs for DebugBaseEventCallbacks interfaces<commit_after>#ifdef _WIN32

#include <pd_backend.h>
#include <assert.h>
#include <stdio.h>
#include <Dbgeng.h>
#include <string>

struct DbgEngPlugin : public DebugBaseEventCallbacks
{
	PDDebugState state = PDDebugState_noTarget;
	bool hasValidTarget = false;

	std::string targetName;

	IDebugClient* debugClient = nullptr;
	IDebugControl* debugControl = nullptr;

	// IUnknown
	STDMETHOD_(ULONG, AddRef)(THIS);
	STDMETHOD_(ULONG, Release)(THIS);

	// IDebugEventCallbacks
	STDMETHOD(GetInterestMask)(THIS_
		OUT PULONG Mask);
	STDMETHOD(Breakpoint)(THIS_
		IN PDEBUG_BREAKPOINT Bp);
	STDMETHOD(Exception)(THIS_
		IN PEXCEPTION_RECORD64 Exception, IN ULONG FirstChance);
	STDMETHOD(CreateProcess)(THIS_
		IN ULONG64 ImageFileHandle,
		IN ULONG64 Handle,
		IN ULONG64 BaseOffset,
		IN ULONG ModuleSize,
		IN PCSTR ModuleName,
		IN PCSTR ImageName,
		IN ULONG CheckSum,
		IN ULONG TimeDateStamp,
		IN ULONG64 InitialThreadHandle,
		IN ULONG64 ThreadDataOffset,
		IN ULONG64 StartOffset);
	STDMETHOD(LoadModule)(THIS_
		IN ULONG64 ImageFileHandle,
		IN ULONG64 BaseOffset,
		IN ULONG ModuleSize,
		IN PCSTR ModuleName,
		IN PCSTR ImageName,
		IN ULONG CheckSum,
		IN ULONG TimeDateStamp);
	STDMETHOD(SessionStatus)(THIS_
		IN ULONG Status);
};

STDMETHODIMP_(ULONG) DbgEngPlugin::AddRef(THIS)
{
	return 1;
}

STDMETHODIMP_(ULONG) DbgEngPlugin::Release(THIS)
{
	return 0;
}

STDMETHODIMP DbgEngPlugin::GetInterestMask(THIS_
	OUT PULONG Mask)
{
	*Mask =
		DEBUG_EVENT_BREAKPOINT |
		DEBUG_EVENT_EXCEPTION |
		DEBUG_EVENT_CREATE_PROCESS |
		DEBUG_EVENT_LOAD_MODULE |
		DEBUG_EVENT_SESSION_STATUS;
	return S_OK;
}

STDMETHODIMP DbgEngPlugin::Breakpoint(THIS_
	IN PDEBUG_BREAKPOINT Bp)
{
	return S_OK;
}

STDMETHODIMP DbgEngPlugin::Exception(THIS_
	IN PEXCEPTION_RECORD64 Exception,
	IN ULONG FirstChance)
{
	return S_OK;
}

STDMETHODIMP DbgEngPlugin::CreateProcess(THIS_
	IN ULONG64 ImageFileHandle,
	IN ULONG64 Handle,
	IN ULONG64 BaseOffset,
	IN ULONG ModuleSize,
	IN PCSTR ModuleName,
	IN PCSTR ImageName,
	IN ULONG CheckSum,
	IN ULONG TimeDateStamp,
	IN ULONG64 InitialThreadHandle,
	IN ULONG64 ThreadDataOffset,
	IN ULONG64 StartOffset)
{
	return S_OK;
}

STDMETHODIMP DbgEngPlugin::LoadModule(THIS_
	IN ULONG64 ImageFileHandle,
	IN ULONG64 BaseOffset,
	IN ULONG ModuleSize,
	IN PCSTR ModuleName,
	IN PCSTR ImageName,
	IN ULONG CheckSum,
	IN ULONG TimeDateStamp)
{
	return S_OK;
}

STDMETHODIMP DbgEngPlugin::SessionStatus(THIS_
	IN ULONG Status)
{
	return S_OK;
}

static void updateDbgEngEvent(DbgEngPlugin* plugin, PDWriter* writer)
{
	HRESULT hr = plugin->debugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, 100);

	if (hr == S_FALSE)
	{
		// WaitForEvent timeout occurred
		return;
	}

	// TODO: check and handle execution status
}

void onRun(DbgEngPlugin* plugin)
{
	printf("DbgEngPlugin: onRun\n");

	if (plugin->state == PDDebugState_noTarget)
	{
		assert(!plugin->targetName.empty());

		HRESULT hr = plugin->debugClient->CreateProcess(0, PSTR(plugin->targetName.c_str()), DEBUG_ONLY_THIS_PROCESS);
		assert(SUCCEEDED(hr));

		if (SUCCEEDED(hr))
		{
			printf("Error: could not create process '%s'\n", plugin->targetName.c_str());
		}
		else
		{
			printf("Valid target %s\n", plugin->targetName.c_str());
		}

		plugin->state = PDDebugState_running;
	}
}

void onStop(DbgEngPlugin* plugin)
{
	printf("DbgEngPlugin: onStop\n");
}

static void onBreak(DbgEngPlugin* plugin)
{
	printf("DbgEngPlugin: onBreak\n");
}

static void onStep(DbgEngPlugin* plugin)
{
	printf("DbgEngPlugin: onStep\n");
}

static void onStepOver(DbgEngPlugin* plugin)
{
	printf("DbgEngPlugin: onStepOver\n");
}

static void onStepOut(DbgEngPlugin* plugin)
{
	printf("DbgEngPlugin: onStepOut\n");
}

static void doAction(DbgEngPlugin* plugin, PDAction action)
{
	printf("DbgEngPlugin: doAction\n");

	switch (action)
	{
	case PDAction_stop: onStop(plugin); break;
	case PDAction_break: onBreak(plugin); break;
	case PDAction_run: onRun(plugin); break;
	case PDAction_step: onStep(plugin); break;
	case PDAction_stepOut: onStepOut(plugin); break;
	case PDAction_stepOver: onStepOver(plugin); break;
	}
}

static void setExceptionLocation(DbgEngPlugin* plugin, PDWriter* writer)
{
	printf("DbgEngPlugin: setExceptionLocation\n");
}

static void setCallstack(DbgEngPlugin* plugin, PDWriter* writer)
{
	printf("DbgEngPlugin: setCallstack\n");
}

static void setExecutable(DbgEngPlugin* plugin, PDReader* reader)
{
	printf("DbgEngPlugin: setExecutable\n");

	const char* filename = 0;

	PDRead_findString(reader, &filename, "filename", 0);

	if (!filename)
	{
		printf("Unable to find filename which is required when starting a LLDB debug session\n");
		return;
	}

	printf("found filename \"%s\"\n", filename);

	plugin->targetName = filename;
}

static void setLocals(DbgEngPlugin* plugin, PDWriter* writer)
{
	printf("DbgEngPlugin: setLocals\n");
}

static void setBreakpoint(DbgEngPlugin* plugin, PDReader* reader, PDWriter* writer)
{
	printf("DbgEngPlugin: setBreakpoint\n");
}

static void eventAction(DbgEngPlugin* plugin, PDReader* reader)
{
	printf("DbgEngPlugin: eventAction\n");

	uint32_t action = 0;

	printf("DbgEngPlugin; %d\n", (PDRead_findU32(reader, &action, "action", 0) & 0xff) >> 8);
	printf("DbgEngPlugin: got action (from event) %d\n", action);

	doAction(plugin, (PDAction)action);
}

static const char* eventTypes[] =
{
	"PDEventType_none",
	"PDEventType_getLocals",
	"PDEventType_setLocals",
	"PDEventType_getCallstack",
	"PDEventType_setCallstack",
	"PDEventType_getWatch",
	"PDEventType_setWatch",
	"PDEventType_getRegisters",
	"PDEventType_setRegisters",
	"PDEventType_getMemory",
	"PDEventType_setMemory",
	"PDEventType_getTty",
	"PDEventType_setTty",
	"PDEventType_getExceptionLocation",
	"PDEventType_setExceptionLocation",
	"PDEventType_getDisassembly",
	"PDEventType_setDisassembly",
	"PDEventType_setBreakpoint",
	"PDEventType_getBreakpoint",
	"PDEventType_setExecutable",
	"PDEventType_attachToProcess",
	"PDEventType_attachToRemoteSession",
	"PDEventType_action",
};

static void processEvents(DbgEngPlugin* plugin, PDReader* reader, PDWriter* writer)
{
	printf("DbgEngPlugin: processEvents\n");

	PDEventType event;

	while ((event = (PDEventType)PDRead_getEvent(reader)))
	{
		printf("DbgEngPlugin: %d Got event %s\n", (int)event, eventTypes[event]);

		switch (event)
		{
		case PDEventType_getExceptionLocation: setExceptionLocation(plugin, writer); break;
		case PDEventType_getCallstack: setCallstack(plugin, writer); break;
		case PDEventType_setExecutable: setExecutable(plugin, reader); break;
		case PDEventType_getLocals: setLocals(plugin, writer); break;
		case PDEventType_setBreakpoint: setBreakpoint(plugin, reader, writer); break;
		case PDEventType_action: eventAction(plugin, reader); break;
		}
	}
}

void* createInstance(ServiceFunc* serviceFunc)
{
	DbgEngPlugin* plugin = new DbgEngPlugin;

	HRESULT hr = DebugCreate(__uuidof(IDebugClient), (void**)&plugin->debugClient);
	assert(SUCCEEDED(hr));

	hr = plugin->debugClient->SetEventCallbacks(plugin);
	assert(SUCCEEDED(hr));

	hr = plugin->debugClient->QueryInterface(__uuidof(IDebugControl), (void**)&plugin->debugControl);
	assert(SUCCEEDED(hr));

	return plugin;
}

void destroyInstance(void* userData)
{
	DbgEngPlugin* plugin = reinterpret_cast<DbgEngPlugin*>(userData);

	if (plugin->debugControl)
	{
		plugin->debugControl->Release();
		plugin->debugControl = nullptr;
	}

	if (plugin->debugClient)
	{
		plugin->debugClient->Release();
		plugin->debugClient = nullptr;
	}

	delete plugin;
}

static PDDebugState update(void* userData, PDAction action, PDReader* reader, PDWriter* writer)
{
	DbgEngPlugin* plugin = reinterpret_cast<DbgEngPlugin*>(userData);

	processEvents(plugin, reader, writer);

	doAction(plugin, action);

	if (plugin->state == PDDebugState_running)
	{
		updateDbgEngEvent(plugin, writer);
	}

	return plugin->state;
}

static PDBackendPlugin plugin =
{
	"Microsoft Debugger Engine",
	createInstance,
	destroyInstance,
	update,
};

extern "C" PD_EXPORT void InitPlugin(RegisterPlugin* registerPlugin, void* privateData)
{
	registerPlugin(PD_BACKEND_API_VERSION, &plugin, privateData);
}

#endif
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSensors module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef Q_OS_BLACKBERRY
#include "genericorientationsensor.h"
#include "genericrotationsensor.h"
#include "genericalssensor.h"
#endif
#include "generictiltsensor.h"
#include <qsensorplugin.h>
#include <qsensorbackend.h>
#include <qsensormanager.h>
#include <QFile>
#include <QDebug>

class genericSensorPlugin : public QObject, public QSensorPluginInterface, public QSensorChangesInterface, public QSensorBackendFactory
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "com.nokia.Qt.QSensorPluginInterface/1.0" FILE "plugin.json")
    Q_INTERFACES(QSensorPluginInterface QSensorChangesInterface)
public:
    void registerSensors()
    {
        qDebug() << "loaded the Generic plugin";
        // Nothing to register here
    }

    void sensorsChanged()
    {
        if (!QSensor::defaultSensorForType(QAccelerometer::type).isEmpty()) {
            // There is an accelerometer available. Register the backends
#ifndef Q_OS_BLACKBERRY
            if (!QSensorManager::isBackendRegistered(QOrientationSensor::type, genericorientationsensor::id))
                QSensorManager::registerBackend(QOrientationSensor::type, genericorientationsensor::id, this);
            if (!QSensorManager::isBackendRegistered(QRotationSensor::type, genericrotationsensor::id))
                QSensorManager::registerBackend(QRotationSensor::type, genericrotationsensor::id, this);
            if (!QSensorManager::isBackendRegistered(QAmbientLightSensor::type, genericalssensor::id))
                QSensorManager::registerBackend(QAmbientLightSensor::type, genericalssensor::id, this);
#endif
            if (!QSensorManager::isBackendRegistered(QTiltSensor::type, GenericTiltSensor::id))
                QSensorManager::registerBackend(QTiltSensor::type, GenericTiltSensor::id, this);
        } else {
#ifndef Q_OS_BLACKBERRY
            if (QSensorManager::isBackendRegistered(QOrientationSensor::type, genericorientationsensor::id))
                QSensorManager::unregisterBackend(QOrientationSensor::type, genericorientationsensor::id);
            if (QSensorManager::isBackendRegistered(QRotationSensor::type, genericrotationsensor::id))
                QSensorManager::unregisterBackend(QRotationSensor::type, genericrotationsensor::id);
            if (QSensorManager::isBackendRegistered(QAmbientLightSensor::type, genericalssensor::id))
                QSensorManager::unregisterBackend(QAmbientLightSensor::type, genericalssensor::id);
#endif
            if (QSensorManager::isBackendRegistered(QTiltSensor::type, GenericTiltSensor::id))
                QSensorManager::unregisterBackend(QTiltSensor::type, GenericTiltSensor::id);
        }
    }

    QSensorBackend *createBackend(QSensor *sensor)
    {
#ifndef Q_OS_BLACKBERRY
        if (sensor->identifier() == genericorientationsensor::id)
            return new genericorientationsensor(sensor);

        if (sensor->identifier() == genericrotationsensor::id)
            return new genericrotationsensor(sensor);

        if (sensor->identifier() == genericalssensor::id)
            return new genericalssensor(sensor);
#endif
        if (sensor->identifier() == GenericTiltSensor::id)
            return new GenericTiltSensor(sensor);

        return 0;
    }
};

#include "main.moc"

<commit_msg>Generic plugin: Remove debug message noise.<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSensors module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef Q_OS_BLACKBERRY
#include "genericorientationsensor.h"
#include "genericrotationsensor.h"
#include "genericalssensor.h"
#endif
#include "generictiltsensor.h"
#include <qsensorplugin.h>
#include <qsensorbackend.h>
#include <qsensormanager.h>
#include <QFile>
#include <QDebug>

class genericSensorPlugin : public QObject, public QSensorPluginInterface, public QSensorChangesInterface, public QSensorBackendFactory
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "com.nokia.Qt.QSensorPluginInterface/1.0" FILE "plugin.json")
    Q_INTERFACES(QSensorPluginInterface QSensorChangesInterface)
public:
    void registerSensors()
    {
        // Nothing to register here
    }

    void sensorsChanged()
    {
        if (!QSensor::defaultSensorForType(QAccelerometer::type).isEmpty()) {
            // There is an accelerometer available. Register the backends
#ifndef Q_OS_BLACKBERRY
            if (!QSensorManager::isBackendRegistered(QOrientationSensor::type, genericorientationsensor::id))
                QSensorManager::registerBackend(QOrientationSensor::type, genericorientationsensor::id, this);
            if (!QSensorManager::isBackendRegistered(QRotationSensor::type, genericrotationsensor::id))
                QSensorManager::registerBackend(QRotationSensor::type, genericrotationsensor::id, this);
            if (!QSensorManager::isBackendRegistered(QAmbientLightSensor::type, genericalssensor::id))
                QSensorManager::registerBackend(QAmbientLightSensor::type, genericalssensor::id, this);
#endif
            if (!QSensorManager::isBackendRegistered(QTiltSensor::type, GenericTiltSensor::id))
                QSensorManager::registerBackend(QTiltSensor::type, GenericTiltSensor::id, this);
        } else {
#ifndef Q_OS_BLACKBERRY
            if (QSensorManager::isBackendRegistered(QOrientationSensor::type, genericorientationsensor::id))
                QSensorManager::unregisterBackend(QOrientationSensor::type, genericorientationsensor::id);
            if (QSensorManager::isBackendRegistered(QRotationSensor::type, genericrotationsensor::id))
                QSensorManager::unregisterBackend(QRotationSensor::type, genericrotationsensor::id);
            if (QSensorManager::isBackendRegistered(QAmbientLightSensor::type, genericalssensor::id))
                QSensorManager::unregisterBackend(QAmbientLightSensor::type, genericalssensor::id);
#endif
            if (QSensorManager::isBackendRegistered(QTiltSensor::type, GenericTiltSensor::id))
                QSensorManager::unregisterBackend(QTiltSensor::type, GenericTiltSensor::id);
        }
    }

    QSensorBackend *createBackend(QSensor *sensor)
    {
#ifndef Q_OS_BLACKBERRY
        if (sensor->identifier() == genericorientationsensor::id)
            return new genericorientationsensor(sensor);

        if (sensor->identifier() == genericrotationsensor::id)
            return new genericrotationsensor(sensor);

        if (sensor->identifier() == genericalssensor::id)
            return new genericalssensor(sensor);
#endif
        if (sensor->identifier() == GenericTiltSensor::id)
            return new GenericTiltSensor(sensor);

        return 0;
    }
};

#include "main.moc"

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the V4VM module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qv4objectiterator_p.h"
#include "qv4object_p.h"
#include "qv4stringobject_p.h"
#include "qv4identifier_p.h"

using namespace QV4;

ObjectIterator::ObjectIterator(Object *o, uint flags)
    : object(o)
    , current(o)
    , arrayNode(0)
    , arrayIndex(0)
    , memberIndex(0)
    , flags(flags)
{
    tmpDynamicProperty.value = Value::undefinedValue();
}

Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *attrs)
{
    Property *p = 0;
    *name = 0;
    *index = UINT_MAX;
    while (1) {
        if (!current)
            break;

        p = current->advanceIterator(this, name, index, attrs);
        if (p)
            return p;

        if (flags & WithProtoChain)
            current = current->prototype;
        else
            current = 0;

        arrayIndex = 0;
        memberIndex = 0;
    }
    return 0;
}

Value ObjectIterator::nextPropertyName(Value *value)
{
    PropertyAttributes attrs;
    uint index;
    String *name;
    Property *p = next(&name, &index, &attrs);
    if (!p)
        return Value::nullValue();

    if (value)
        *value = object->getValue(object->engine()->current, p, attrs);

    if (name)
        return Value::fromString(name);
    assert(index < UINT_MAX);
    return Value::fromDouble(index);
}

Value ObjectIterator::nextPropertyNameAsString(Value *value)
{
    PropertyAttributes attrs;
    uint index;
    String *name;
    Property *p = next(&name, &index, &attrs);
    if (!p)
        return Value::nullValue();

    if (value)
        *value = object->getValue(object->engine()->current, p, attrs);

    if (name)
        return Value::fromString(name);
    assert(index < UINT_MAX);
    return Value::fromString(object->engine()->newString(QString::number(index)));
}
<commit_msg>Fix for..in with duplicated properties<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the V4VM module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qv4objectiterator_p.h"
#include "qv4object_p.h"
#include "qv4stringobject_p.h"
#include "qv4identifier_p.h"

using namespace QV4;

ObjectIterator::ObjectIterator(Object *o, uint flags)
    : object(o)
    , current(o)
    , arrayNode(0)
    , arrayIndex(0)
    , memberIndex(0)
    , flags(flags)
{
    tmpDynamicProperty.value = Value::undefinedValue();
}

Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *attrs)
{
    Property *p = 0;
    *name = 0;
    *index = UINT_MAX;
    while (1) {
        if (!current)
            break;

        while (p = current->advanceIterator(this, name, index, attrs)) {
            // check the property is not already defined earlier in the proto chain
            if (current != object) {
                Property *pp;
                if (*name) {
                    pp = object->__getPropertyDescriptor__(*name);
                } else {
                    assert (*index != UINT_MAX);
                    pp = object->__getPropertyDescriptor__(*index);
                }
                if (pp != p)
                    continue;
            }
            return p;
        }

        if (flags & WithProtoChain)
            current = current->prototype;
        else
            current = 0;

        arrayIndex = 0;
        memberIndex = 0;
    }
    return 0;
}

Value ObjectIterator::nextPropertyName(Value *value)
{
    PropertyAttributes attrs;
    uint index;
    String *name;
    Property *p = next(&name, &index, &attrs);
    if (!p)
        return Value::nullValue();

    if (value)
        *value = object->getValue(object->engine()->current, p, attrs);

    if (name)
        return Value::fromString(name);
    assert(index < UINT_MAX);
    return Value::fromDouble(index);
}

Value ObjectIterator::nextPropertyNameAsString(Value *value)
{
    PropertyAttributes attrs;
    uint index;
    String *name;
    Property *p = next(&name, &index, &attrs);
    if (!p)
        return Value::nullValue();

    if (value)
        *value = object->getValue(object->engine()->current, p, attrs);

    if (name)
        return Value::fromString(name);
    assert(index < UINT_MAX);
    return Value::fromString(object->engine()->newString(QString::number(index)));
}
<|endoftext|>


<commit_before>#include "rdb_protocol/terms/terms.hpp"

#include <string>

#include "rdb_protocol/op.hpp"
#include "rdb_protocol/error.hpp"
#include "rdb_protocol/pb_utils.hpp"

namespace ql {

// This term is used for functions that are polymorphic on objects and
// sequences, like `pluck`.  It will handle the polymorphism; terms inheriting
// from it just need to implement evaluation on objects (`obj_eval`).
class obj_or_seq_op_term_t : public op_term_t {
public:
    enum poly_type_t {
        MAP = 0,
        FILTER = 1
    };
    obj_or_seq_op_term_t(env_t *env, protob_t<const Term> term,
                         poly_type_t _poly_type, argspec_t argspec)
        : op_term_t(env, term, argspec), poly_type(_poly_type),
          func(make_counted_term()) {
        int varnum = env->gensym();
        Term *body = pb::set_func(func.get(), varnum);
        *body = *term;
        pb::set_var(pb::reset(body->mutable_args(0)), varnum);
        prop_bt(func.get());
    }
private:
    virtual counted_t<val_t> obj_eval() = 0;
    virtual counted_t<val_t> eval_impl() {
        counted_t<val_t> v0 = arg(0);
        if (v0->get_type().is_convertible(val_t::type_t::DATUM)) {
            if (v0->as_datum()->get_type() == datum_t::R_OBJECT) return obj_eval();
        }
        if (v0->get_type().is_convertible(val_t::type_t::SEQUENCE)) {
            switch (poly_type) {
            case MAP:
                return new_val(v0->as_seq()->map(make_counted<func_t>(env, func)));
            case FILTER:
                return new_val(v0->as_seq()->filter(make_counted<func_t>(env, func)));
            default: unreachable();
            }
            unreachable();
        }
        rfail("Cannot perform %s on a non-object non-sequence.", name());
        unreachable();
    }

    poly_type_t poly_type;
    protob_t<Term> func;
};

class pluck_term_t : public obj_or_seq_op_term_t {
public:
    pluck_term_t(env_t *env, protob_t<const Term> term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval() {
        counted_t<const datum_t> obj = arg(0)->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        scoped_ptr_t<datum_t> out(new datum_t(datum_t::R_OBJECT));
        for (size_t i = 1; i < num_args(); ++i) {
            const std::string &key = arg(i)->as_str();
            counted_t<const datum_t> el = obj->get(key);
            if (el.has()) {
                bool conflict = out->add(key, el);
                r_sanity_check(!conflict);
            }
        }
        return new_val(counted_t<const datum_t>(out.release()));
    }
    virtual const char *name() const { return "pluck"; }
};

class without_term_t : public obj_or_seq_op_term_t {
public:
    without_term_t(env_t *env, protob_t<const Term> term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval() {
        counted_t<const datum_t> obj = arg(0)->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        scoped_ptr_t<datum_t> out(new datum_t(obj->as_object()));
        for (size_t i = 1; i < num_args(); ++i) {
            const std::string &key = arg(i)->as_str();
            UNUSED bool b = out->delete_key(key);
        }
        return new_val(counted_t<const datum_t>(out.release()));
    }
    virtual const char *name() const { return "without"; }
};

class merge_term_t : public obj_or_seq_op_term_t {
public:
    merge_term_t(env_t *env, protob_t<const Term> term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval() {
        counted_t<const datum_t> d = arg(0)->as_datum();
        for (size_t i = 1; i < num_args(); ++i) {
            d = d->merge(arg(i)->as_datum());
        }
        return new_val(d);
    }
    virtual const char *name() const { return "merge"; }
};

class has_fields_term_t : public obj_or_seq_op_term_t {
public:
    has_fields_term_t(env_t *env, protob_t<const Term> term)
        : obj_or_seq_op_term_t(env, term, FILTER, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval() {
        counted_t<const datum_t> obj = arg(0)->as_datum();
        for (size_t i = 1; i < num_args(); ++i) {
            counted_t<const datum_t> el = obj->get(arg(i)->as_str(), NOTHROW);
            if (!el.has() || el->get_type() == datum_t::R_NULL) {
                return new_val_bool(false);
            }
        }
        return new_val_bool(true);
    }
    virtual const char *name() const { return "has_fields"; }
};

counted_t<term_t> make_has_fields_term(env_t *env, protob_t<const Term> term) {
    return make_counted<has_fields_term_t>(env, term);
}

counted_t<term_t> make_pluck_term(env_t *env, protob_t<const Term> term) {
    return make_counted<pluck_term_t>(env, term);
}
counted_t<term_t> make_without_term(env_t *env, protob_t<const Term> term) {
    return make_counted<without_term_t>(env, term);
}
counted_t<term_t> make_merge_term(env_t *env, protob_t<const Term> term) {
    return make_counted<merge_term_t>(env, term);
}

} // namespace ql
<commit_msg>fixed pluck and without to not be quadratic<commit_after>#include "rdb_protocol/terms/terms.hpp"

#include <string>

#include "rdb_protocol/op.hpp"
#include "rdb_protocol/error.hpp"
#include "rdb_protocol/pb_utils.hpp"

namespace ql {

// This term is used for functions that are polymorphic on objects and
// sequences, like `pluck`.  It will handle the polymorphism; terms inheriting
// from it just need to implement evaluation on objects (`obj_eval`).
class obj_or_seq_op_term_t : public op_term_t {
public:
    enum poly_type_t {
        MAP = 0,
        FILTER = 1
    };
    obj_or_seq_op_term_t(env_t *env, protob_t<const Term> term,
                         poly_type_t _poly_type, argspec_t argspec)
        : op_term_t(env, term, argspec), poly_type(_poly_type),
          func(make_counted_term()) {
        int varnum = env->gensym();
        Term *body = pb::set_func(func.get(), varnum);
        *body = *term;
        pb::set_var(pb::reset(body->mutable_args(0)), varnum);
        prop_bt(func.get());
    }
private:
    virtual counted_t<val_t> obj_eval(counted_t<val_t> v0) = 0;
    virtual counted_t<val_t> eval_impl() {
        counted_t<val_t> v0 = arg(0);
        if (v0->get_type().is_convertible(val_t::type_t::DATUM)) {
            if (v0->as_datum()->get_type() == datum_t::R_OBJECT) return obj_eval(v0);
        }
        if (v0->get_type().is_convertible(val_t::type_t::SEQUENCE)) {
            switch (poly_type) {
            case MAP:
                return new_val(v0->as_seq()->map(make_counted<func_t>(env, func)));
            case FILTER:
                return new_val(v0->as_seq()->filter(make_counted<func_t>(env, func)));
            default: unreachable();
            }
            unreachable();
        }
        rfail("Cannot perform %s on a non-object non-sequence.", name());
        unreachable();
    }

    poly_type_t poly_type;
    protob_t<Term> func;
};

class pluck_term_t : public obj_or_seq_op_term_t {
public:
    pluck_term_t(env_t *env, protob_t<const Term> term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        scoped_ptr_t<datum_t> out(new datum_t(datum_t::R_OBJECT));
        for (size_t i = 1; i < num_args(); ++i) {
            const std::string &key = arg(i)->as_str();
            counted_t<const datum_t> el = obj->get(key);
            if (el.has()) {
                bool conflict = out->add(key, el);
                r_sanity_check(!conflict);
            }
        }
        return new_val(counted_t<const datum_t>(out.release()));
    }
    virtual const char *name() const { return "pluck"; }
};

class without_term_t : public obj_or_seq_op_term_t {
public:
    without_term_t(env_t *env, protob_t<const Term> term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        r_sanity_check(obj->get_type() == datum_t::R_OBJECT);

        scoped_ptr_t<datum_t> out(new datum_t(obj->as_object()));
        for (size_t i = 1; i < num_args(); ++i) {
            const std::string &key = arg(i)->as_str();
            UNUSED bool b = out->delete_key(key);
        }
        return new_val(counted_t<const datum_t>(out.release()));
    }
    virtual const char *name() const { return "without"; }
};

class merge_term_t : public obj_or_seq_op_term_t {
public:
    merge_term_t(env_t *env, protob_t<const Term> term) :
        obj_or_seq_op_term_t(env, term, MAP, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(counted_t<val_t> v0) {
        counted_t<const datum_t> d = v0->as_datum();
        for (size_t i = 1; i < num_args(); ++i) {
            d = d->merge(arg(i)->as_datum());
        }
        return new_val(d);
    }
    virtual const char *name() const { return "merge"; }
};

class has_fields_term_t : public obj_or_seq_op_term_t {
public:
    has_fields_term_t(env_t *env, protob_t<const Term> term)
        : obj_or_seq_op_term_t(env, term, FILTER, argspec_t(1, -1)) { }
private:
    virtual counted_t<val_t> obj_eval(counted_t<val_t> v0) {
        counted_t<const datum_t> obj = v0->as_datum();
        for (size_t i = 1; i < num_args(); ++i) {
            counted_t<const datum_t> el = obj->get(arg(i)->as_str(), NOTHROW);
            if (!el.has() || el->get_type() == datum_t::R_NULL) {
                return new_val_bool(false);
            }
        }
        return new_val_bool(true);
    }
    virtual const char *name() const { return "has_fields"; }
};

counted_t<term_t> make_has_fields_term(env_t *env, protob_t<const Term> term) {
    return make_counted<has_fields_term_t>(env, term);
}

counted_t<term_t> make_pluck_term(env_t *env, protob_t<const Term> term) {
    return make_counted<pluck_term_t>(env, term);
}
counted_t<term_t> make_without_term(env_t *env, protob_t<const Term> term) {
    return make_counted<without_term_t>(env, term);
}
counted_t<term_t> make_merge_term(env_t *env, protob_t<const Term> term) {
    return make_counted<merge_term_t>(env, term);
}

} // namespace ql
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "catch.hpp"

#include "dll/dbn.hpp"
#include "dll/text_reader.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("dbn/mnist_1", "dbn::simple") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(500);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}

TEST_CASE("dbn/mnist_2", "dbn::containers") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(500);

    REQUIRE(!dataset.training_images.empty());
    dataset.training_images.resize(200);
    dataset.training_labels.resize(200);

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 5);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 5);

    REQUIRE(error < 5e-2);
}

TEST_CASE("dbn/mnist_3", "dbn::labels") {
    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(1000);
    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    typedef dll::dbn_desc<
        dll::dbn_label_layers<
            dll::rbm_desc<28 * 28, 200, dll::batch_size<50>, dll::init_weights, dll::momentum>::layer_t,
            dll::rbm_desc<200, 300, dll::batch_size<50>, dll::momentum>::layer_t,
            dll::rbm_desc<310, 500, dll::batch_size<50>, dll::momentum>::layer_t>,
        dll::batch_size<10>>::dbn_t dbn_t;

    auto dbn = std::make_unique<dbn_t>();

    dbn->train_with_labels(dataset.training_images, dataset.training_labels, 10, 10);

    auto error = dll::test_set(dbn, dataset.training_images, dataset.training_labels, dll::label_predictor());
    std::cout << "test_error:" << error << std::endl;
    REQUIRE(error < 0.3);
}

TEST_CASE("dbn/mnist_6", "dbn::cg_gaussian") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 200, dll::momentum, dll::batch_size<25>, dll::visible<dll::unit_type::GAUSSIAN>>::layer_t,
            dll::rbm_desc<200, 500, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<500, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(1000);

    REQUIRE(!dataset.training_images.empty());

    mnist::normalize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}

//This test should not perform well, but should not fail
TEST_CASE("dbn/mnist_8", "dbn::cg_relu") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::RELU>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(200);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(std::isfinite(error));

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;
}

TEST_CASE("dbn/mnist_15", "dbn::parallel") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::parallel_mode, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::parallel_mode, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::parallel_mode, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(500);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}

TEST_CASE("dbn/mnist_17", "dbn::memory") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_mode, dll::batch_size<50>, dll::big_batch_size<3>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(1078);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(
        dataset.training_images.begin(), dataset.training_images.end(),
        dataset.training_labels.begin(), dataset.training_labels.end(),
        10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);

    //Mostly here to ensure compilation
    auto out = dbn->prepare_one_output<etl::dyn_matrix<float, 1>>();
    REQUIRE(out.size() > 0);
}

TEST_CASE("dbn/mnist/text/1", "dbn::simple") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto training_images = dll::text::read_images<std::vector, etl::dyn_matrix<float, 1>>(
        "/home/wichtounet/datasets/mnist_text/train/images", 500,
        [](){ return etl::dyn_matrix<float, 1>(28 * 28);});

    auto test_images = dll::text::read_images<std::vector, etl::dyn_matrix<float, 1>>(
        "/home/wichtounet/datasets/mnist_text/test/images", 500,
        [](){ return etl::dyn_matrix<float, 1>(28 * 28);});

    auto training_labels = dll::text::read_labels<std::vector, uint8_t>("/home/wichtounet/datasets/mnist_text/train/labels", 500);
    auto test_labels = dll::text::read_labels<std::vector, uint8_t>("/home/wichtounet/datasets/mnist_text/test/labels", 500);

    REQUIRE(training_images.size() == 500);
    REQUIRE(test_images.size() == 500);
    REQUIRE(training_labels.size() == 500);
    REQUIRE(test_labels.size() == 500);

    mnist::binarize_each(training_images);
    mnist::binarize_each(test_images);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(training_images, 20);
    auto error = dbn->fine_tune(training_images, training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, test_images, test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}
<commit_msg>Review the test<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "catch.hpp"

#include "dll/dbn.hpp"
#include "dll/text_reader.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("dbn/mnist_1", "dbn::simple") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(500);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}

TEST_CASE("dbn/mnist_2", "dbn::containers") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(500);

    REQUIRE(!dataset.training_images.empty());
    dataset.training_images.resize(200);
    dataset.training_labels.resize(200);

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 5);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 5);

    REQUIRE(error < 5e-2);
}

TEST_CASE("dbn/mnist_3", "dbn::labels") {
    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(1000);
    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    typedef dll::dbn_desc<
        dll::dbn_label_layers<
            dll::rbm_desc<28 * 28, 200, dll::batch_size<50>, dll::init_weights, dll::momentum>::layer_t,
            dll::rbm_desc<200, 300, dll::batch_size<50>, dll::momentum>::layer_t,
            dll::rbm_desc<310, 500, dll::batch_size<50>, dll::momentum>::layer_t>,
        dll::batch_size<10>>::dbn_t dbn_t;

    auto dbn = std::make_unique<dbn_t>();

    dbn->train_with_labels(dataset.training_images, dataset.training_labels, 10, 10);

    auto error = dll::test_set(dbn, dataset.training_images, dataset.training_labels, dll::label_predictor());
    std::cout << "test_error:" << error << std::endl;
    REQUIRE(error < 0.3);
}

TEST_CASE("dbn/mnist_6", "dbn::cg_gaussian") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 200, dll::momentum, dll::batch_size<25>, dll::visible<dll::unit_type::GAUSSIAN>>::layer_t,
            dll::rbm_desc<200, 500, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<500, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(1000);

    REQUIRE(!dataset.training_images.empty());

    mnist::normalize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}

//This test should not perform well, but should not fail
TEST_CASE("dbn/mnist_8", "dbn::cg_relu") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::RELU>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(200);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(std::isfinite(error));

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;
}

TEST_CASE("dbn/mnist_15", "dbn::parallel") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::parallel_mode, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::parallel_mode, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::parallel_mode, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(500);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}

TEST_CASE("dbn/mnist_17", "dbn::memory") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_mode, dll::batch_size<50>, dll::big_batch_size<3>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::dyn_matrix<float, 1>>(1078);

    REQUIRE(!dataset.training_images.empty());

    mnist::binarize_dataset(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(dataset.training_images, 20);
    auto error = dbn->fine_tune(
        dataset.training_images.begin(), dataset.training_images.end(),
        dataset.training_labels.begin(), dataset.training_labels.end(),
        10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);

    //Mostly here to ensure compilation
    auto out = dbn->prepare_one_output<etl::dyn_matrix<float, 1>>();
    REQUIRE(out.size() > 0);
}

TEST_CASE("dbn/mnist/text/1", "dbn::simple") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::rbm_desc<28 * 28, 100, dll::momentum, dll::batch_size<25>, dll::init_weights>::layer_t,
            dll::rbm_desc<100, 200, dll::momentum, dll::batch_size<25>>::layer_t,
            dll::rbm_desc<200, 10, dll::momentum, dll::batch_size<25>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::batch_size<50>>::dbn_t dbn_t;

    auto training_images = dll::text::read_images<std::vector, etl::dyn_matrix<float, 1>, false>(
        "/home/wichtounet/datasets/mnist_text/train/images", 500);

    auto test_images = dll::text::read_images<std::vector, etl::dyn_matrix<float, 1>, false>(
        "/home/wichtounet/datasets/mnist_text/test/images", 500);

    auto training_labels = dll::text::read_labels<std::vector, uint8_t>("/home/wichtounet/datasets/mnist_text/train/labels", 500);
    auto test_labels = dll::text::read_labels<std::vector, uint8_t>("/home/wichtounet/datasets/mnist_text/test/labels", 500);

    REQUIRE(training_images.size() == 500);
    REQUIRE(test_images.size() == 500);
    REQUIRE(training_labels.size() == 500);
    REQUIRE(test_labels.size() == 500);

    mnist::binarize_each(training_images);
    mnist::binarize_each(test_images);

    auto dbn = std::make_unique<dbn_t>();

    dbn->pretrain(training_images, 20);
    auto error = dbn->fine_tune(training_images, training_labels, 10);

    REQUIRE(error < 5e-2);

    auto test_error = dll::test_set(dbn, test_images, test_labels, dll::predictor());

    std::cout << "test_error:" << test_error << std::endl;

    REQUIRE(test_error < 0.2);
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
//
// 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/StdList>
#include <Eigen/Geometry>

template<typename MatrixType>
void check_stdlist_matrix(const MatrixType& m)
{
  int rows = m.rows();
  int cols = m.cols();
  MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
  std::list<MatrixType,Eigen::aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);
  v.front() = x;
  w.front() = w.back();
  VERIFY_IS_APPROX(w.front(), w.back());
  v = w;

  typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator vi = v.begin();
  typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator wi = w.begin();
  for(int i = 0; i < 20; i++)
  {
    VERIFY_IS_APPROX(*vi, *wi);
    ++vi;
    ++wi;
  }

  v.resize(21);
  v.back() = x;
  if (!test_ei_isApprox(v.back(),x))
  {
    std::cout << x << std::endl;
    std::cout << v.back() << std::endl;
  }
  VERIFY_IS_APPROX(v.back(), x);
  v.resize(22,y);
  VERIFY_IS_APPROX(v.back(), y);
  v.push_back(x);
  VERIFY_IS_APPROX(v.back(), x);
}

template<typename TransformType>
void check_stdlist_transform(const TransformType&)
{
  typedef typename TransformType::MatrixType MatrixType;
  TransformType x(MatrixType::Random()), y(MatrixType::Random());
  std::list<TransformType,Eigen::aligned_allocator<TransformType> > v(10), w(20, y);
  v.front() = x;
  w.front() = w.back();
  VERIFY_IS_APPROX(w.front(), w.back());
  v = w;

  typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator vi = v.begin();
  typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator wi = w.begin();
  for(int i = 0; i < 20; i++)
  {
    VERIFY_IS_APPROX(*vi, *wi);
    ++vi;
    ++wi;
  }

  v.resize(21);
  v.back() = x;
  VERIFY_IS_APPROX(v.back(), x);
  v.resize(22,y);
  VERIFY_IS_APPROX(v.back(), y);
  v.push_back(x);
  VERIFY_IS_APPROX(v.back(), x);
}

template<typename QuaternionType>
void check_stdlist_quaternion(const QuaternionType&)
{
  typedef typename QuaternionType::Coefficients Coefficients;
  QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
  std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> > v(10), w(20, y);
  v.front() = x;
  w.front() = w.back();
  VERIFY_IS_APPROX(w.front(), w.back());
  v = w;

  typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator vi = v.begin();
  typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator wi = w.begin();
  for(int i = 0; i < 20; i++)
  {
    VERIFY_IS_APPROX(*vi, *wi);
    ++vi;
    ++wi;
  }

  v.resize(21);
  v.back() = x;
  VERIFY_IS_APPROX(v.back(), x);
  v.resize(22,y);
  VERIFY_IS_APPROX(v.back(), y);
  v.push_back(x);
  if (!test_ei_isApprox(v.back(),x))
  {
    std::cout << x << std::endl;
    std::cout << v.back() << std::endl;
  }
  VERIFY_IS_APPROX(v.back(), x);
}

void test_stdlist()
{
  // some non vectorizable fixed sizes
  CALL_SUBTEST_1(check_stdlist_matrix(Vector2f()));
  CALL_SUBTEST_1(check_stdlist_matrix(Matrix3f()));
  CALL_SUBTEST_2(check_stdlist_matrix(Matrix3d()));

  // some vectorizable fixed sizes
  CALL_SUBTEST_1(check_stdlist_matrix(Matrix2f()));
  CALL_SUBTEST_1(check_stdlist_matrix(Vector4f()));
  CALL_SUBTEST_1(check_stdlist_matrix(Matrix4f()));
  CALL_SUBTEST_2(check_stdlist_matrix(Matrix4d()));

  // some dynamic sizes
  CALL_SUBTEST_3(check_stdlist_matrix(MatrixXd(1,1)));
  CALL_SUBTEST_3(check_stdlist_matrix(VectorXd(20)));
  CALL_SUBTEST_3(check_stdlist_matrix(RowVectorXf(20)));
  CALL_SUBTEST_3(check_stdlist_matrix(MatrixXcf(10,10)));

  // some Transform
  CALL_SUBTEST_4(check_stdlist_transform(Transform2f()));
  CALL_SUBTEST_4(check_stdlist_transform(Transform3f()));
  CALL_SUBTEST_4(check_stdlist_transform(Transform3d()));
  //CALL_SUBTEST(heck_stdvector_transform(Transform4d()));

  // some Quaternion
  CALL_SUBTEST_5(check_stdlist_quaternion(Quaternionf()));
  CALL_SUBTEST_5(check_stdlist_quaternion(Quaterniond()));
}
<commit_msg>Remove printouts.<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
//
// 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/StdList>
#include <Eigen/Geometry>

template<typename MatrixType>
void check_stdlist_matrix(const MatrixType& m)
{
  int rows = m.rows();
  int cols = m.cols();
  MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);
  std::list<MatrixType,Eigen::aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);
  v.front() = x;
  w.front() = w.back();
  VERIFY_IS_APPROX(w.front(), w.back());
  v = w;

  typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator vi = v.begin();
  typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator wi = w.begin();
  for(int i = 0; i < 20; i++)
  {
    VERIFY_IS_APPROX(*vi, *wi);
    ++vi;
    ++wi;
  }

  v.resize(21);
  v.back() = x;
  VERIFY_IS_APPROX(v.back(), x);
  v.resize(22,y);
  VERIFY_IS_APPROX(v.back(), y);
  v.push_back(x);
  VERIFY_IS_APPROX(v.back(), x);
}

template<typename TransformType>
void check_stdlist_transform(const TransformType&)
{
  typedef typename TransformType::MatrixType MatrixType;
  TransformType x(MatrixType::Random()), y(MatrixType::Random());
  std::list<TransformType,Eigen::aligned_allocator<TransformType> > v(10), w(20, y);
  v.front() = x;
  w.front() = w.back();
  VERIFY_IS_APPROX(w.front(), w.back());
  v = w;

  typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator vi = v.begin();
  typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator wi = w.begin();
  for(int i = 0; i < 20; i++)
  {
    VERIFY_IS_APPROX(*vi, *wi);
    ++vi;
    ++wi;
  }

  v.resize(21);
  v.back() = x;
  VERIFY_IS_APPROX(v.back(), x);
  v.resize(22,y);
  VERIFY_IS_APPROX(v.back(), y);
  v.push_back(x);
  VERIFY_IS_APPROX(v.back(), x);
}

template<typename QuaternionType>
void check_stdlist_quaternion(const QuaternionType&)
{
  typedef typename QuaternionType::Coefficients Coefficients;
  QuaternionType x(Coefficients::Random()), y(Coefficients::Random());
  std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> > v(10), w(20, y);
  v.front() = x;
  w.front() = w.back();
  VERIFY_IS_APPROX(w.front(), w.back());
  v = w;

  typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator vi = v.begin();
  typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator wi = w.begin();
  for(int i = 0; i < 20; i++)
  {
    VERIFY_IS_APPROX(*vi, *wi);
    ++vi;
    ++wi;
  }

  v.resize(21);
  v.back() = x;
  VERIFY_IS_APPROX(v.back(), x);
  v.resize(22,y);
  VERIFY_IS_APPROX(v.back(), y);
  v.push_back(x);
  VERIFY_IS_APPROX(v.back(), x);
}

void test_stdlist()
{
  // some non vectorizable fixed sizes
  CALL_SUBTEST_1(check_stdlist_matrix(Vector2f()));
  CALL_SUBTEST_1(check_stdlist_matrix(Matrix3f()));
  CALL_SUBTEST_2(check_stdlist_matrix(Matrix3d()));

  // some vectorizable fixed sizes
  CALL_SUBTEST_1(check_stdlist_matrix(Matrix2f()));
  CALL_SUBTEST_1(check_stdlist_matrix(Vector4f()));
  CALL_SUBTEST_1(check_stdlist_matrix(Matrix4f()));
  CALL_SUBTEST_2(check_stdlist_matrix(Matrix4d()));

  // some dynamic sizes
  CALL_SUBTEST_3(check_stdlist_matrix(MatrixXd(1,1)));
  CALL_SUBTEST_3(check_stdlist_matrix(VectorXd(20)));
  CALL_SUBTEST_3(check_stdlist_matrix(RowVectorXf(20)));
  CALL_SUBTEST_3(check_stdlist_matrix(MatrixXcf(10,10)));

  // some Transform
  CALL_SUBTEST_4(check_stdlist_transform(Transform2f()));
  CALL_SUBTEST_4(check_stdlist_transform(Transform3f()));
  CALL_SUBTEST_4(check_stdlist_transform(Transform3d()));
  //CALL_SUBTEST(heck_stdvector_transform(Transform4d()));

  // some Quaternion
  CALL_SUBTEST_5(check_stdlist_quaternion(Quaternionf()));
  CALL_SUBTEST_5(check_stdlist_quaternion(Quaterniond()));
}
<|endoftext|>