<commit_before>/*
 * opencog/learning/moses/moses/types.cc
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * All Rights Reserved
 *
 * Written by Moshe Looks
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "types.h"
#include "complexity.h"

#include <sstream>

namespace opencog { namespace moses {

using namespace std;

demeID_t::demeID_t(unsigned expansion)
    : string(to_string(expansion)) {}
demeID_t::demeID_t(unsigned expansion, unsigned breadth_first)
    : string(to_string(expansion) + "." + to_string(breadth_first)) {}

bool pbscored_combo_tree_greater::operator()(const pbscored_combo_tree& bs_tr1,
                                            const pbscored_combo_tree& bs_tr2) const
{
    composite_score csc1 = get_composite_score(bs_tr1);
    composite_score csc2 = get_composite_score(bs_tr2);

    bool gt = (csc1 > csc2);
    if (gt) return true;

    bool lt = (csc1 < csc2);
    if (lt) return false;

    // If we are here, then they are equal.  We are desperate to break
    // a tie, because otherwise, the pbscored_combo_tree_set will discard
    // anything that compares equal, and we really don't want that.
    score_t sc1 = get_score(csc1);
    score_t sc2 = get_score(csc2);

    gt = (sc1 > sc2);
    if (gt) return true;

    lt = (sc1 < sc2);
    if (lt) return false;

    // Arghh, still tied!  The above already used complexity to break
    // the tie.  We're grasping at straws, here.
    return size_tree_order<vertex>()(get_tree(bs_tr1), get_tree(bs_tr2));
    return res;
}

// the empty composite_score ctor returns the worst composite score
const composite_score worst_composite_score = composite_score();

composite_score::composite_score()
    : score(very_worst_score), complexity(worst_complexity),
      complexity_penalty(0.0), diversity_penalty(0.0),
      penalized_score(very_worst_score)
{}

composite_score& composite_score::operator=(const composite_score &r)
{
    score = r.score;
    complexity = r.complexity;
    penalized_score = r.penalized_score;
    complexity_penalty = r.complexity_penalty;
    diversity_penalty = r.diversity_penalty;
    multiply_diversity = r.multiply_diversity;
    return *this;
}

bool composite_score::operator<(const composite_score &r) const
{
    score_t lef = penalized_score;
    score_t rig = r.penalized_score;

    if (isnan(lef))
        return !isnan(rig);
    else
        return (lef < rig)
                // Note: I've tried to see if the addition below
                // increases the performance when there is no
                // complexity penalty and it doesn't, over 100 runs
                // solving 3-parity is actually .5s slower (which
                // probably has no statistical significance given it
                // takes 13s in average). But I don't want to conclude
                // too fast, it could have an impact on other
                // problems.
                or (lef == rig and complexity > r.complexity);
}

// Check for equality, to within floating-point error.
bool composite_score::operator==(const composite_score &r) const
{
    // score_t and complexity_t are both defacto floats.
    // equality holds if they are equal within about 7 decimal places.
    // Note: this check is used in iostream_bscored_combo_treeUTest
    // and a simple equality test will fail on some cpu/os combos.
    #define FLOAT_EPS 1.0e-7
    #define CHK_EQ(NAME)  \
        ((NAME == r.get_##NAME()) || /* Try this cheap test first */ \
         (fabs(NAME) > 0.0f) ?  \
            (fabs(r.get_##NAME() / NAME - 1.0f) < FLOAT_EPS) : \
            (fabs(NAME - r.get_##NAME()) < FLOAT_EPS))
    return
        CHK_EQ(score)
        && CHK_EQ(complexity)
        && CHK_EQ(complexity_penalty)
        && CHK_EQ(diversity_penalty)
        && CHK_EQ(penalized_score)
        ;
}

///////////////////////////
// convenience accessors //
///////////////////////////

const combo::combo_tree& get_tree(const pbscored_combo_tree& pbst)
{
    return pbst.first;
}

combo::combo_tree& get_tree(pbscored_combo_tree& pbst)
{
    return pbst.first;
}

const composite_penalized_bscore& get_composite_penalized_bscore(const pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

composite_penalized_bscore& get_composite_penalized_bscore(pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

const cpbscore_demeID& get_cpbscore_demeID(const pbscored_combo_tree& pbst) {
    return pbst.second;
}

cpbscore_demeID& get_cpbscore_demeID(pbscored_combo_tree& pbst) {
    return pbst.second;
}

demeID_t get_demeID(const pbscored_combo_tree& pbst)
{
    return pbst.second.second;
}

score_t get_penalized_score(const composite_score& sc)
{
   return sc.get_penalized_score();
}

const composite_score& get_composite_score(const composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

const composite_score& get_composite_score(const pbscored_combo_tree& bsct)
{
    return get_composite_score(get_composite_penalized_bscore(bsct));
}

score_t get_penalized_score(const composite_penalized_bscore& cpb)
{
    return get_penalized_score(get_composite_score(cpb));
}

score_t get_penalized_score(const pbscored_combo_tree& st)
{
    return get_penalized_score(get_composite_score(st));
}

composite_score& get_composite_score(composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

composite_score& get_composite_score(pbscored_combo_tree& bsct)
{
    return get_composite_score(bsct.second.first);
}

score_t get_score(const composite_score& ts)
{
    return ts.get_score();
}

score_t get_score(const composite_penalized_bscore& ts)
{
    return get_score(ts.second);
}

score_t get_score(const pbscored_combo_tree& bst)
{
    return get_score(get_composite_penalized_bscore(bst));
}

complexity_t get_complexity(const composite_score& ts)
{
    return ts.get_complexity();
}

complexity_t get_complexity(const composite_penalized_bscore& ts)
{
    return get_complexity(ts.second);
}

complexity_t get_complexity(const pbscored_combo_tree& bst)
{
    return get_complexity(get_composite_penalized_bscore(bst));
}

score_t get_complexity_penalty(const composite_score& ts)
{
    return ts.get_complexity_penalty();
}

score_t get_complexity_penalty(const composite_penalized_bscore& ts)
{
    return get_complexity_penalty(ts.second);
}

score_t get_complexity_penalty(const pbscored_combo_tree& bst)
{
    return get_complexity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_diversity_penalty(const composite_score& ts)
{
    return ts.get_diversity_penalty();
}

score_t get_diversity_penalty(const composite_penalized_bscore& ts)
{
    return get_diversity_penalty(ts.second);
}

score_t get_diversity_penalty(const pbscored_combo_tree& bst)
{
    return get_diversity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_penalty(const composite_score& ts)
{
    return ts.get_penalty();
}

score_t get_penalty(const composite_penalized_bscore& ts)
{
    return get_penalty(ts.second);
}

score_t get_penalty(const pbscored_combo_tree& bst)
{
    return get_penalty(get_composite_penalized_bscore(bst));
}

const penalized_bscore& get_pbscore(const composite_penalized_bscore& ts)
{
    return ts.first;
}

penalized_bscore& get_pbscore(composite_penalized_bscore& ts)
{
    return ts.first;
}

const penalized_bscore& get_pbscore(const pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

penalized_bscore& get_pbscore(pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

const behavioral_score& get_bscore(const penalized_bscore& pbs)
{
    return pbs.first;
}

const behavioral_score& get_bscore(const composite_penalized_bscore& cbs)
{
    return get_bscore(cbs.first);
}

const behavioral_score& get_bscore(const pbscored_combo_tree& bst)
{
    return get_bscore(get_composite_penalized_bscore(bst));
}

} // ~namespace moses
} // ~namespace opencog
<commit_msg>Remove dumb return<commit_after>/*
 * opencog/learning/moses/moses/types.cc
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * All Rights Reserved
 *
 * Written by Moshe Looks
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "types.h"
#include "complexity.h"

#include <sstream>

namespace opencog { namespace moses {

using namespace std;

demeID_t::demeID_t(unsigned expansion)
    : string(to_string(expansion)) {}
demeID_t::demeID_t(unsigned expansion, unsigned breadth_first)
    : string(to_string(expansion) + "." + to_string(breadth_first)) {}

bool pbscored_combo_tree_greater::operator()(const pbscored_combo_tree& bs_tr1,
                                            const pbscored_combo_tree& bs_tr2) const
{
    composite_score csc1 = get_composite_score(bs_tr1);
    composite_score csc2 = get_composite_score(bs_tr2);

    bool gt = (csc1 > csc2);
    if (gt) return true;

    bool lt = (csc1 < csc2);
    if (lt) return false;

    // If we are here, then they are equal.  We are desperate to break
    // a tie, because otherwise, the pbscored_combo_tree_set will discard
    // anything that compares equal, and we really don't want that.
    score_t sc1 = get_score(csc1);
    score_t sc2 = get_score(csc2);

    gt = (sc1 > sc2);
    if (gt) return true;

    lt = (sc1 < sc2);
    if (lt) return false;

    // Arghh, still tied!  The above already used complexity to break
    // the tie.  We're grasping at straws, here.
    return size_tree_order<vertex>()(get_tree(bs_tr1), get_tree(bs_tr2));
}

// the empty composite_score ctor returns the worst composite score
const composite_score worst_composite_score = composite_score();

composite_score::composite_score()
    : score(very_worst_score), complexity(worst_complexity),
      complexity_penalty(0.0), diversity_penalty(0.0),
      penalized_score(very_worst_score)
{}

composite_score& composite_score::operator=(const composite_score &r)
{
    score = r.score;
    complexity = r.complexity;
    penalized_score = r.penalized_score;
    complexity_penalty = r.complexity_penalty;
    diversity_penalty = r.diversity_penalty;
    multiply_diversity = r.multiply_diversity;
    return *this;
}

bool composite_score::operator<(const composite_score &r) const
{
    score_t lef = penalized_score;
    score_t rig = r.penalized_score;

    if (isnan(lef))
        return !isnan(rig);
    else
        return (lef < rig)
                // Note: I've tried to see if the addition below
                // increases the performance when there is no
                // complexity penalty and it doesn't, over 100 runs
                // solving 3-parity is actually .5s slower (which
                // probably has no statistical significance given it
                // takes 13s in average). But I don't want to conclude
                // too fast, it could have an impact on other
                // problems.
                or (lef == rig and complexity > r.complexity);
}

// Check for equality, to within floating-point error.
bool composite_score::operator==(const composite_score &r) const
{
    // score_t and complexity_t are both defacto floats.
    // equality holds if they are equal within about 7 decimal places.
    // Note: this check is used in iostream_bscored_combo_treeUTest
    // and a simple equality test will fail on some cpu/os combos.
    #define FLOAT_EPS 1.0e-7
    #define CHK_EQ(NAME)  \
        ((NAME == r.get_##NAME()) || /* Try this cheap test first */ \
         (fabs(NAME) > 0.0f) ?  \
            (fabs(r.get_##NAME() / NAME - 1.0f) < FLOAT_EPS) : \
            (fabs(NAME - r.get_##NAME()) < FLOAT_EPS))
    return
        CHK_EQ(score)
        && CHK_EQ(complexity)
        && CHK_EQ(complexity_penalty)
        && CHK_EQ(diversity_penalty)
        && CHK_EQ(penalized_score)
        ;
}

///////////////////////////
// convenience accessors //
///////////////////////////

const combo::combo_tree& get_tree(const pbscored_combo_tree& pbst)
{
    return pbst.first;
}

combo::combo_tree& get_tree(pbscored_combo_tree& pbst)
{
    return pbst.first;
}

const composite_penalized_bscore& get_composite_penalized_bscore(const pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

composite_penalized_bscore& get_composite_penalized_bscore(pbscored_combo_tree& pbst)
{
    return pbst.second.first;
}

const cpbscore_demeID& get_cpbscore_demeID(const pbscored_combo_tree& pbst) {
    return pbst.second;
}

cpbscore_demeID& get_cpbscore_demeID(pbscored_combo_tree& pbst) {
    return pbst.second;
}

demeID_t get_demeID(const pbscored_combo_tree& pbst)
{
    return pbst.second.second;
}

score_t get_penalized_score(const composite_score& sc)
{
   return sc.get_penalized_score();
}

const composite_score& get_composite_score(const composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

const composite_score& get_composite_score(const pbscored_combo_tree& bsct)
{
    return get_composite_score(get_composite_penalized_bscore(bsct));
}

score_t get_penalized_score(const composite_penalized_bscore& cpb)
{
    return get_penalized_score(get_composite_score(cpb));
}

score_t get_penalized_score(const pbscored_combo_tree& st)
{
    return get_penalized_score(get_composite_score(st));
}

composite_score& get_composite_score(composite_penalized_bscore& ctbs)
{
    return ctbs.second;
}

composite_score& get_composite_score(pbscored_combo_tree& bsct)
{
    return get_composite_score(bsct.second.first);
}

score_t get_score(const composite_score& ts)
{
    return ts.get_score();
}

score_t get_score(const composite_penalized_bscore& ts)
{
    return get_score(ts.second);
}

score_t get_score(const pbscored_combo_tree& bst)
{
    return get_score(get_composite_penalized_bscore(bst));
}

complexity_t get_complexity(const composite_score& ts)
{
    return ts.get_complexity();
}

complexity_t get_complexity(const composite_penalized_bscore& ts)
{
    return get_complexity(ts.second);
}

complexity_t get_complexity(const pbscored_combo_tree& bst)
{
    return get_complexity(get_composite_penalized_bscore(bst));
}

score_t get_complexity_penalty(const composite_score& ts)
{
    return ts.get_complexity_penalty();
}

score_t get_complexity_penalty(const composite_penalized_bscore& ts)
{
    return get_complexity_penalty(ts.second);
}

score_t get_complexity_penalty(const pbscored_combo_tree& bst)
{
    return get_complexity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_diversity_penalty(const composite_score& ts)
{
    return ts.get_diversity_penalty();
}

score_t get_diversity_penalty(const composite_penalized_bscore& ts)
{
    return get_diversity_penalty(ts.second);
}

score_t get_diversity_penalty(const pbscored_combo_tree& bst)
{
    return get_diversity_penalty(get_composite_penalized_bscore(bst));
}

score_t get_penalty(const composite_score& ts)
{
    return ts.get_penalty();
}

score_t get_penalty(const composite_penalized_bscore& ts)
{
    return get_penalty(ts.second);
}

score_t get_penalty(const pbscored_combo_tree& bst)
{
    return get_penalty(get_composite_penalized_bscore(bst));
}

const penalized_bscore& get_pbscore(const composite_penalized_bscore& ts)
{
    return ts.first;
}

penalized_bscore& get_pbscore(composite_penalized_bscore& ts)
{
    return ts.first;
}

const penalized_bscore& get_pbscore(const pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

penalized_bscore& get_pbscore(pbscored_combo_tree& bst)
{
    return get_pbscore(get_composite_penalized_bscore(bst));
}

const behavioral_score& get_bscore(const penalized_bscore& pbs)
{
    return pbs.first;
}

const behavioral_score& get_bscore(const composite_penalized_bscore& cbs)
{
    return get_bscore(cbs.first);
}

const behavioral_score& get_bscore(const pbscored_combo_tree& bst)
{
    return get_bscore(get_composite_penalized_bscore(bst));
}

} // ~namespace moses
} // ~namespace opencog
<|endoftext|>


<commit_before>/*
    Copyright (c) 2013, Taiga Nomi
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
    names of its contributors may be used to endorse or promote products
    derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <iostream>
#include "tiny_cnn/tiny_cnn.h"

using namespace tiny_cnn;
using namespace tiny_cnn::activation;

void construct_net(network<sequential>& nn) {
    // connection table [Y.Lecun, 1998 Table.1]
#define O true
#define X false
    static const bool tbl[] = {
        O, X, X, X, O, O, O, X, X, O, O, O, O, X, O, O,
        O, O, X, X, X, O, O, O, X, X, O, O, O, O, X, O,
        O, O, O, X, X, X, O, O, O, X, X, O, X, O, O, O,
        X, O, O, O, X, X, O, O, O, O, X, X, O, X, O, O,
        X, X, O, O, O, X, X, O, O, O, O, X, O, O, X, O,
        X, X, X, O, O, O, X, X, O, O, O, O, X, O, O, O
    };
#undef O
#undef X

    // construct nets
    nn << convolutional_layer<tan_h>(32, 32, 5, 1, 6)  // C1, 1@32x32-in, 6@28x28-out
       << average_pooling_layer<tan_h>(28, 28, 6, 2)   // S2, 6@28x28-in, 6@14x14-out
       << convolutional_layer<tan_h>(14, 14, 5, 6, 16,
            connection_table(tbl, 6, 16))              // C3, 6@14x14-in, 16@10x10-in
       << average_pooling_layer<tan_h>(10, 10, 16, 2)  // S4, 16@10x10-in, 16@5x5-out
       << deconvolutional_layer<tan_h>(5, 5, 5, 16, 120) // C5, 16@5x5-in, 120@1x1-out
       << fully_connected_layer<tan_h>(120, 10);       // F6, 120-in, 10-out
}

void train_lenet(std::string data_dir_path) {
    // specify loss-function and learning strategy
    network<sequential> nn;
    adagrad optimizer;

    construct_net(nn);

    std::cout << "load models..." << std::endl;

    // load MNIST dataset
    std::vector<label_t> train_labels, test_labels;
    std::vector<vec_t> train_images, test_images;

    parse_mnist_labels(data_dir_path+"/train-labels.idx1-ubyte",
                       &train_labels);
    parse_mnist_images(data_dir_path+"/train-images.idx3-ubyte",
                       &train_images, -1.0, 1.0, 2, 2);
    parse_mnist_labels(data_dir_path+"/t10k-labels.idx1-ubyte",
                       &test_labels);
    parse_mnist_images(data_dir_path+"/t10k-images.idx3-ubyte",
                       &test_images, -1.0, 1.0, 2, 2);

    std::cout << "start training" << std::endl;

    progress_display disp(train_images.size());
    timer t;
    int minibatch_size = 10;
    int num_epochs = 30;

    optimizer.alpha *= std::sqrt(minibatch_size);

    // create callback
    auto on_enumerate_epoch = [&](){
        std::cout << t.elapsed() << "s elapsed." << std::endl;
        tiny_cnn::result res = nn.test(test_images, test_labels);
        std::cout << res.num_success << "/" << res.num_total << std::endl;

        disp.restart(train_images.size());
        t.restart();
    };

    auto on_enumerate_minibatch = [&](){
        disp += minibatch_size;
    };

    // training
    nn.train<mse>(optimizer, train_images, train_labels, minibatch_size, num_epochs,
             on_enumerate_minibatch, on_enumerate_epoch);

    std::cout << "end training." << std::endl;

    // test and show results
    nn.test(test_images, test_labels).print_detail(std::cout);

    // save networks
    std::ofstream ofs("LeNet-weights");
    ofs << nn;
}

int main(int argc, char **argv) {
    if (argc != 2) {
        std::cerr << "Usage : " << argv[0]
                  << " path_to_data (example:../data)" << std::endl;
        return -1;
    }
    train_lenet(argv[1]);
}
<commit_msg>Implement on deconvolution and unpooling layer.<commit_after>/*
    Copyright (c) 2013, Taiga Nomi
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
    names of its contributors may be used to endorse or promote products
    derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <iostream>
#include "tiny_cnn/tiny_cnn.h"

using namespace tiny_cnn;
using namespace tiny_cnn::activation;

void construct_net(network<sequential>& nn) {
    // connection table [Y.Lecun, 1998 Table.1]
#define O true
#define X false
    static const bool tbl[] = {
        O, X, X, X, O, O, O, X, X, O, O, O, O, X, O, O,
        O, O, X, X, X, O, O, O, X, X, O, O, O, O, X, O,
        O, O, O, X, X, X, O, O, O, X, X, O, X, O, O, O,
        X, O, O, O, X, X, O, O, O, O, X, X, O, X, O, O,
        X, X, O, O, O, X, X, O, O, O, O, X, O, O, X, O,
        X, X, X, O, O, O, X, X, O, O, O, O, X, O, O, O
    };
#undef O
#undef X

    // construct nets
    nn << deconvolutional_layer<tan_h>(32, 32, 5, 1, 6)  // D1, 1@32x32-in, 6@36x36-out
       << average_pooling_layer<tan_h>(36, 36, 6, 2)   // S2, 6@36x36-in, 6@18x18-out
       << deconvolutional_layer<tan_h>(18, 18, 5, 6, 16,
            connection_table(tbl, 6, 16))              // D3, 6@18x18-in, 16@22x22-out
       << average_pooling_layer<tan_h>(22, 22, 16, 2)  // S4, 16@22x22-in, 16@11x11-out
       << deconvolutional_layer<tan_h>(11, 11, 5, 16, 16) // D5, 16@11x11-in, 16@15x15-out
       << average_pooling_layer<tan_h>(15, 15, 16, 3)  // S6, 16@15x15-in, 5@5x5-out
       << convolutional_layer<tan_h>(5, 5, 5, 16, 120) // C7, 16@5x5-in, 120@1x1-out
       << fully_connected_layer<tan_h>(120, 10);       // F8, 120-in, 10-out
}

void train_lenet(std::string data_dir_path) {
    // specify loss-function and learning strategy
    network<sequential> nn;
    adagrad optimizer;

    construct_net(nn);

    std::cout << "load models..." << std::endl;

    // load MNIST dataset
    std::vector<label_t> train_labels, test_labels;
    std::vector<vec_t> train_images, test_images;

    parse_mnist_labels(data_dir_path+"/train-labels.idx1-ubyte",
                       &train_labels);
    parse_mnist_images(data_dir_path+"/train-images.idx3-ubyte",
                       &train_images, -1.0, 1.0, 2, 2);
    parse_mnist_labels(data_dir_path+"/t10k-labels.idx1-ubyte",
                       &test_labels);
    parse_mnist_images(data_dir_path+"/t10k-images.idx3-ubyte",
                       &test_images, -1.0, 1.0, 2, 2);

    std::cout << "start training" << std::endl;

    progress_display disp(train_images.size());
    timer t;
    int minibatch_size = 10;
    int num_epochs = 30;

    optimizer.alpha *= std::sqrt(minibatch_size);

    // create callback
    auto on_enumerate_epoch = [&](){
        std::cout << t.elapsed() << "s elapsed." << std::endl;
        tiny_cnn::result res = nn.test(test_images, test_labels);
        std::cout << res.num_success << "/" << res.num_total << std::endl;

        disp.restart(train_images.size());
        t.restart();
    };

    auto on_enumerate_minibatch = [&](){
        disp += minibatch_size;
    };

    // training
    nn.train<mse>(optimizer, train_images, train_labels, minibatch_size, num_epochs,
             on_enumerate_minibatch, on_enumerate_epoch);

    std::cout << "end training." << std::endl;

    // test and show results
    nn.test(test_images, test_labels).print_detail(std::cout);

    // save networks
    std::ofstream ofs("LeNet-weights");
    ofs << nn;
}

int main(int argc, char **argv) {
    if (argc != 2) {
        std::cerr << "Usage : " << argv[0]
                  << " path_to_data (example:../data)" << std::endl;
        return -1;
    }
    train_lenet(argv[1]);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Aldebaran Robotics. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the COPYING file.
 */

#pragma once
#ifndef _QI_CLOCK_HPP_
# define _QI_CLOCK_HPP_

# include <qi/api.hpp>
# include <qi/types.hpp>
# include <boost/chrono.hpp>

namespace qi
{
  /// Convenience typedefs
  typedef boost::chrono::duration<int64_t, boost::nano>         Duration;
  typedef boost::chrono::duration<int64_t, boost::nano>         NanoSeconds;
  typedef boost::chrono::duration<int64_t, boost::micro>        MicroSeconds;
  typedef boost::chrono::duration<int64_t, boost::milli>        MilliSeconds;
  typedef boost::chrono::duration<int64_t>                      Seconds;
  typedef boost::chrono::duration<int64_t, boost::ratio<60> >   Minutes;
  typedef boost::chrono::duration<int64_t, boost::ratio<3600> > Hours;

  /**
   * \brief The SteadyClock class represents a monotonic clock.
   * \includename{qi/clock.hpp}
   *
   * The time points of this clock cannot decrease as physical
   * time moves forward. This clock is not related to wall clock time,
   * and is best suitable for measuring intervals.
   */
  class QI_API SteadyClock
  {
  public:
    typedef int64_t rep; ///< The representation type of the duration and time_point.
    typedef boost::nano period; ///< The tick period of the clock in nanoseconds.
    typedef boost::chrono::duration<rep, period> duration; ///< The duration type of the clock.
    /**
     * The time_point type of the clock. Different clocks are permitted
     * to share a time_point definition if it is valid to compare their
     * time_points by comparing their respective durations.
     */
    typedef boost::chrono::time_point<boost::chrono::steady_clock> time_point;
    /**
     * true if t1 <= t2 is always true, else false.
     * \note A clock that can be adjusted backwards is not steady.
     */
    BOOST_STATIC_CONSTEXPR bool is_steady = boost::chrono::steady_clock::is_steady;

  public:
    /// Returns a time_point representing a point in time.
    typedef boost::chrono::time_point<boost::chrono::steady_clock> SteadyClockTimePoint;

     /// \brief Enum expected argument
    enum Expect {
      Expect_SoonerOrLater, ///< Pick the nearest result to user-provided reference.
      Expect_Later,         ///< Result is expected to be later than user-provided reference.
      Expect_Sooner         ///< Result is expected to be sooner than user-provided reference.
    };

    /// Returns a time_point representing the current value of the clock.
    static SteadyClockTimePoint now();

    /**
     * \brief Convert the time point to a number of milliseconds on 32 bits.
     *
     * Since the 32 bits number overflows every 2^32 ms ~ 50 days,
     * this is a lossy operation.
     * \param t The time point to convert.
     * \return Unsigned int representing the time.
     */
    static uint32_t toUint32ms(const SteadyClockTimePoint &t) throw();
    /**
     * \brief Convert the time point to a number of milliseconds on 32 bits.
     *
     * Since the 32 bits number overflows every 2^32 ms ~ 50 days,
     * this is a lossy operation.
     * \param t The time point to convert.
     * \return Integer (int) representing the time.
     */
    static int32_t toInt32ms(const SteadyClockTimePoint &t) throw();

    /**
     * \brief Get a time point from a number of milliseconds on 32 bits.
     *
     * Since the 32 bits number overflows every ~50 days, an infinity of
     * time points match a given 32 bits number (all modulo ~50 days).
     * This function picks the result near the guess timepoint depending on
     * the expect argument:
     *
     *   - if expect == LATER, result is expected to be later than guess:
     *     guess <= result < guess + period
     *
     *   - if expect == SOONER, result is expected to be sooner than guess:
     *     guess - period < result <= guess
     *
     *   - if expect == SOONER_OR_LATER, pick the nearest result:
     *     guess - period/2 < result <= guess + period/2
     *
     * where period == 2^32 ms ~ 50 days
     */
    static time_point fromUint32ms(uint32_t t_ms, SteadyClockTimePoint guess,
                                   Expect expect=Expect_SoonerOrLater) throw();
    /// \copydoc SteadyClock::fromUint32ms
    static time_point fromInt32ms(int32_t t_ms, SteadyClockTimePoint guess,
                                  Expect expect=Expect_SoonerOrLater) throw();
  };

  /**
   * \brief The WallClock class represents the system-wide real time wall clock.
   *        It may not be monotonic: on most systems, the system time can be adjusted
   *        at any moment.
   *
   * \includename{qi/clock.hpp}
   */
  class QI_API WallClock
  {
  public:
    typedef int64_t rep; ///< The representation type of the duration and time_point.
    typedef boost::nano period; ///< The tick period of the clock in nanoseconds.
    typedef boost::chrono::duration<rep, period> duration; ///< The duration type of the clock.
    /**
     * The time_point type of the clock. Different clocks are permitted
     * to share a time_point definition if it is valid to compare their
     * time_points by comparing their respective durations.
     */
    typedef boost::chrono::time_point<boost::chrono::system_clock> time_point;
    /// true if t1 <= t2 is always true, else false.
    /// \note A Wallclock is never steady.
    BOOST_STATIC_CONSTEXPR bool is_steady = false;

  public:
    /// Returns a time_point representing a point in time.
    typedef boost::chrono::time_point<boost::chrono::system_clock> WallClockTimePoint;

    /// Returns a time_point representing the current value of the clock.
    static WallClockTimePoint now();

    /**
     * \brief Converts a system clock time point to std::time_t
     * \param t Time point to convert.
     * \return A std::time_t representing \p t.
     */
    static std::time_t to_time_t(const WallClockTimePoint& t) throw();

    // Converts std::time_t to a system clock time point
    /**
     * \brief Converts std::time_t to a system clock time point
     * \param t std::time to convert.
     * \return A WallClockTimePoint representing \p t.
     */
    static WallClockTimePoint from_time_t(const std::time_t &t) throw();
  };

  typedef SteadyClock::SteadyClockTimePoint SteadyClockTimePoint; ///< Steady clock time point.
  typedef WallClock::WallClockTimePoint WallClockTimePoint;       ///< Wall clock time point.

  /// \copydoc SteadyClock::now()
  inline QI_API SteadyClockTimePoint steadyClockNow() {
    return SteadyClock::now();
  }

  /// \copydoc WallClock::now()
  inline QI_API WallClockTimePoint wallClockNow() {
    return WallClock::now();
  }

  /// @{
  /// Blocks the execution of the current thread for at least \p d.
  QI_API void sleepFor(const qi::Duration& d);
  template <class Rep, class Period>
  inline void sleepFor(const boost::chrono::duration<Rep, Period>& d);
  /// @}

  /// @{
  /// \brief Blocks the execution of the current thread until \p t has been reached.
  ///
  /// This is equivalent to sleep_for(SteadyClockTimePoint::now())
  QI_API void sleepUntil(const SteadyClockTimePoint &t);
  template <class Duration>
  inline void sleepUntil(const boost::chrono::time_point<boost::chrono::steady_clock, Duration>& t);
  /// @}

  /// @{
  /// \brief Blocks the execution of the current thread until \p t has been reached.
  ///
  /// Adjustments of the clock are taken into account.
  /// Thus the duration of the block might, but might not, be less
  /// or more than t - WallClock::now()
  QI_API void sleepUntil(const WallClockTimePoint& t);
  template <class Duration>
  inline void sleepUntil(const boost::chrono::time_point<boost::chrono::system_clock, Duration>& t);
  /// @}
}

# ifdef __APPLE__
  // export template instanciation for RTTI issues across libraries. (mostly for OSX)
  template class QI_API boost::chrono::duration<int64_t, boost::nano>;
  template class QI_API boost::chrono::duration<int64_t, boost::micro>;
  template class QI_API boost::chrono::duration<int64_t, boost::milli>;
  template class QI_API boost::chrono::duration<int64_t>;
  template class QI_API boost::chrono::duration<int64_t, boost::ratio<60> >;
  template class QI_API boost::chrono::duration<int64_t, boost::ratio<3600> >;
  template class QI_API boost::chrono::time_point<qi::SteadyClock>;
  template class QI_API boost::chrono::time_point<qi::WallClock>;
# endif

# include <qi/detail/clock.hxx>

#endif  // _QI_OS_HPP_
<commit_msg>Fix typedef export on MacOS<commit_after>/*
 * Copyright (c) 2013 Aldebaran Robotics. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the COPYING file.
 */

#pragma once
#ifndef _QI_CLOCK_HPP_
# define _QI_CLOCK_HPP_

# include <qi/api.hpp>
# include <qi/types.hpp>
# include <boost/chrono.hpp>

namespace qi
{
  /// Convenience typedefs
  typedef boost::chrono::duration<int64_t, boost::nano>         Duration;
  typedef boost::chrono::duration<int64_t, boost::nano>         NanoSeconds;
  typedef boost::chrono::duration<int64_t, boost::micro>        MicroSeconds;
  typedef boost::chrono::duration<int64_t, boost::milli>        MilliSeconds;
  typedef boost::chrono::duration<int64_t>                      Seconds;
  typedef boost::chrono::duration<int64_t, boost::ratio<60> >   Minutes;
  typedef boost::chrono::duration<int64_t, boost::ratio<3600> > Hours;

  /**
   * \brief The SteadyClock class represents a monotonic clock.
   * \includename{qi/clock.hpp}
   *
   * The time points of this clock cannot decrease as physical
   * time moves forward. This clock is not related to wall clock time,
   * and is best suitable for measuring intervals.
   */
  class QI_API SteadyClock
  {
  public:
    typedef int64_t rep; ///< The representation type of the duration and time_point.
    typedef boost::nano period; ///< The tick period of the clock in nanoseconds.
    typedef boost::chrono::duration<rep, period> duration; ///< The duration type of the clock.
    /**
     * The time_point type of the clock. Different clocks are permitted
     * to share a time_point definition if it is valid to compare their
     * time_points by comparing their respective durations.
     */
    typedef boost::chrono::time_point<boost::chrono::steady_clock> time_point;
    /**
     * true if t1 <= t2 is always true, else false.
     * \note A clock that can be adjusted backwards is not steady.
     */
    BOOST_STATIC_CONSTEXPR bool is_steady = boost::chrono::steady_clock::is_steady;

  public:
    /// Returns a time_point representing a point in time.
    typedef boost::chrono::time_point<boost::chrono::steady_clock> SteadyClockTimePoint;

     /// \brief Enum expected argument
    enum Expect {
      Expect_SoonerOrLater, ///< Pick the nearest result to user-provided reference.
      Expect_Later,         ///< Result is expected to be later than user-provided reference.
      Expect_Sooner         ///< Result is expected to be sooner than user-provided reference.
    };

    /// Returns a time_point representing the current value of the clock.
    static SteadyClockTimePoint now();

    /**
     * \brief Convert the time point to a number of milliseconds on 32 bits.
     *
     * Since the 32 bits number overflows every 2^32 ms ~ 50 days,
     * this is a lossy operation.
     * \param t The time point to convert.
     * \return Unsigned int representing the time.
     */
    static uint32_t toUint32ms(const SteadyClockTimePoint &t) throw();
    /**
     * \brief Convert the time point to a number of milliseconds on 32 bits.
     *
     * Since the 32 bits number overflows every 2^32 ms ~ 50 days,
     * this is a lossy operation.
     * \param t The time point to convert.
     * \return Integer (int) representing the time.
     */
    static int32_t toInt32ms(const SteadyClockTimePoint &t) throw();

    /**
     * \brief Get a time point from a number of milliseconds on 32 bits.
     *
     * Since the 32 bits number overflows every ~50 days, an infinity of
     * time points match a given 32 bits number (all modulo ~50 days).
     * This function picks the result near the guess timepoint depending on
     * the expect argument:
     *
     *   - if expect == LATER, result is expected to be later than guess:
     *     guess <= result < guess + period
     *
     *   - if expect == SOONER, result is expected to be sooner than guess:
     *     guess - period < result <= guess
     *
     *   - if expect == SOONER_OR_LATER, pick the nearest result:
     *     guess - period/2 < result <= guess + period/2
     *
     * where period == 2^32 ms ~ 50 days
     */
    static time_point fromUint32ms(uint32_t t_ms, SteadyClockTimePoint guess,
                                   Expect expect=Expect_SoonerOrLater) throw();
    /// \copydoc SteadyClock::fromUint32ms
    static time_point fromInt32ms(int32_t t_ms, SteadyClockTimePoint guess,
                                  Expect expect=Expect_SoonerOrLater) throw();
  };

  /**
   * \brief The WallClock class represents the system-wide real time wall clock.
   *        It may not be monotonic: on most systems, the system time can be adjusted
   *        at any moment.
   *
   * \includename{qi/clock.hpp}
   */
  class QI_API WallClock
  {
  public:
    typedef int64_t rep; ///< The representation type of the duration and time_point.
    typedef boost::nano period; ///< The tick period of the clock in nanoseconds.
    typedef boost::chrono::duration<rep, period> duration; ///< The duration type of the clock.
    /**
     * The time_point type of the clock. Different clocks are permitted
     * to share a time_point definition if it is valid to compare their
     * time_points by comparing their respective durations.
     */
    typedef boost::chrono::time_point<boost::chrono::system_clock> time_point;
    /// true if t1 <= t2 is always true, else false.
    /// \note A Wallclock is never steady.
    BOOST_STATIC_CONSTEXPR bool is_steady = false;

  public:
    /// Returns a time_point representing a point in time.
    typedef boost::chrono::time_point<boost::chrono::system_clock> WallClockTimePoint;

    /// Returns a time_point representing the current value of the clock.
    static WallClockTimePoint now();

    /**
     * \brief Converts a system clock time point to std::time_t
     * \param t Time point to convert.
     * \return A std::time_t representing \p t.
     */
    static std::time_t to_time_t(const WallClockTimePoint& t) throw();

    // Converts std::time_t to a system clock time point
    /**
     * \brief Converts std::time_t to a system clock time point
     * \param t std::time to convert.
     * \return A WallClockTimePoint representing \p t.
     */
    static WallClockTimePoint from_time_t(const std::time_t &t) throw();
  };

  typedef SteadyClock::SteadyClockTimePoint SteadyClockTimePoint; ///< Steady clock time point.
  typedef WallClock::WallClockTimePoint WallClockTimePoint;       ///< Wall clock time point.

  /// \copydoc SteadyClock::now()
  inline QI_API SteadyClockTimePoint steadyClockNow() {
    return SteadyClock::now();
  }

  /// \copydoc WallClock::now()
  inline QI_API WallClockTimePoint wallClockNow() {
    return WallClock::now();
  }

  /// @{
  /// Blocks the execution of the current thread for at least \p d.
  QI_API void sleepFor(const qi::Duration& d);
  template <class Rep, class Period>
  inline void sleepFor(const boost::chrono::duration<Rep, Period>& d);
  /// @}

  /// @{
  /// \brief Blocks the execution of the current thread until \p t has been reached.
  ///
  /// This is equivalent to sleep_for(SteadyClockTimePoint::now())
  QI_API void sleepUntil(const SteadyClockTimePoint &t);
  template <class Duration>
  inline void sleepUntil(const boost::chrono::time_point<boost::chrono::steady_clock, Duration>& t);
  /// @}

  /// @{
  /// \brief Blocks the execution of the current thread until \p t has been reached.
  ///
  /// Adjustments of the clock are taken into account.
  /// Thus the duration of the block might, but might not, be less
  /// or more than t - WallClock::now()
  QI_API void sleepUntil(const WallClockTimePoint& t);
  template <class Duration>
  inline void sleepUntil(const boost::chrono::time_point<boost::chrono::system_clock, Duration>& t);
  /// @}
}

# ifdef __APPLE__
  // export template instanciation for RTTI issues across libraries. (mostly for OSX)
  template class QI_API boost::chrono::duration<int64_t, boost::nano>;
  template class QI_API boost::chrono::duration<int64_t, boost::micro>;
  template class QI_API boost::chrono::duration<int64_t, boost::milli>;
  template class QI_API boost::chrono::duration<int64_t>;
  template class QI_API boost::chrono::duration<int64_t, boost::ratio<60> >;
  template class QI_API boost::chrono::duration<int64_t, boost::ratio<3600> >;
  template class QI_API boost::chrono::time_point<boost::chrono::steady_clock>;
  template class QI_API boost::chrono::time_point<boost::chrono::system_clock>;
# endif

# include <qi/detail/clock.hxx>

#endif  // _QI_OS_HPP_
<|endoftext|>


<commit_before>/*
* oxygenwindowmanager.cpp
* pass some window mouse press/release/move event actions to window manager
* -------------------
*
* Copyright (c) 2010 Cédric Bellegarde <gnumdk@gmail.com>
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
*
* Largely inspired from Qtcurve style
* Copyright (C) Craig Drummond, 2003 - 2010 craig.p.drummond@gmail.com
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or( at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygenwindowmanager.h"
#include "oxygenstyle.h"
#include "config.h"

#include <gdk/gdkx.h>

namespace Oxygen
{

    //_________________________________________________
    WindowManager::WindowManager( void ):
        _mode( Full ),
        _drag( false ),
        _dragDistance( 4 ),
        _dragDelay( 500 ),
        _widget( 0L ),
        _lastRejectedEvent( 0L ),
        _x(-1),
        _y(-1)
    { initializeBlackList(); }

    //_________________________________________________
    WindowManager::~WindowManager( void )
    {
        _map.disconnectAll();
        _map.clear();
    }

    //_________________________________________________
    void WindowManager::registerWidget( GtkWidget* widget )
    {

        if( _map.contains( widget ) || widgetIsBlackListed( widget ) ) return;

        // Window with no decorations (set by app), let window manage it self
        if( GTK_IS_WINDOW( widget ) && !gtk_window_get_decorated( GTK_WINDOW( widget ) ) ) return;

        // widgets used in tabs also must be ignored (happens, unfortunately)
        GtkWidget* parent( gtk_widget_get_parent( widget ) );
        if( GTK_IS_NOTEBOOK( parent ) && Gtk::gtk_notebook_is_tab_label( GTK_NOTEBOOK( parent ), widget ) )
        { return; }

        #if OXYGEN_DEBUG
        std::cout << "Oxygen::WindowManager::registerWidget - " << widget << "(" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
        #endif

        // Force widget to listen to relevant events
        gtk_widget_add_events( widget,
            GDK_BUTTON_RELEASE_MASK |
            GDK_BUTTON_PRESS_MASK   |
            GDK_LEAVE_NOTIFY_MASK   |
            GDK_BUTTON1_MOTION_MASK );

        // allocate new Data object
        Data& data( _map.registerWidget( widget ) );

        // connect signals
        if( _mode != Disabled ) connect( widget, data );

    }

    //_________________________________________________
    void WindowManager::unregisterWidget( GtkWidget* widget )
    {
        if( !_map.contains( widget ) ) return;

        #if OXYGEN_DEBUG
        std::cout << "Oxygen::WindowManager::unregisterWidget - " << widget << "(" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
        #endif

        _map.value( widget ).disconnect( widget );
        _map.erase( widget );

        if( _widget == widget )
        {
            _widget = 0L;
            _x = -1;
            _y = -1;
            _drag = false;
        }

    }

    //_________________________________________________
    void WindowManager::setMode( WindowManager::Mode mode )
    {
        if( mode == _mode ) return;

        // connect/disconnect all data in map, based on new and old mode
        if( mode == Disabled ) { _map.disconnectAll(); }
        else if( _mode == Disabled )
        {
            DataMap<Data>::Map& map( _map.map() );
            for( DataMap<Data>::Map::iterator iter = map.begin(); iter != map.end(); ++iter )
            { connect( iter->first, iter->second ); }
        }

        // assign new mode
        _mode = mode;

    }

    //_________________________________________________
    gboolean WindowManager::wmStyleSet( GtkWidget* widget, GtkStyle* , gpointer data )
    {
        static_cast<WindowManager*>(data)->unregisterWidget( widget );
        return false;
    }

    //_________________________________________________
    gboolean WindowManager::wmDestroy( GtkWidget* widget, gpointer data )
    {
        static_cast<WindowManager*>(data)->unregisterWidget( widget );
        return false;
    }

    //_________________________________________________
    gboolean WindowManager::wmButtonPress(GtkWidget *widget, GdkEventButton* event, gpointer data )
    {

        if( event->type == GDK_BUTTON_PRESS && event->button == Gtk::LeftButton )
        {

            #if OXYGEN_DEBUG
            std::cout << "Oxygen::WindowManager::wmButtonPress -"
                << " event: " << event
                << " widget: " << widget
                << "(" << G_OBJECT_TYPE_NAME( widget ) << ")"
                << " " << gtk_widget_get_name( widget )
                << std::endl;
            #endif

            return static_cast<WindowManager*>(data)->isWindowDragWidget( widget, event );

        } else return false;

    }

    //_________________________________________________
    gboolean WindowManager::wmButtonRelease(GtkWidget *widget, GdkEventButton*, gpointer data )
    { return static_cast<WindowManager*>( data )->finishDrag( widget ); }

    //_________________________________________________
    gboolean WindowManager::wmLeave(GtkWidget *widget, GdkEventCrossing*, gpointer data )
    { return static_cast<WindowManager*>( data )->finishDrag( widget ); }

    //_________________________________________________
    gboolean WindowManager::wmMotion( GtkWidget *widget, GdkEventMotion* event, gpointer data )
    { return static_cast<WindowManager*>(data)->startDrag( widget, event ); }

    //_________________________________________________________________
    gboolean WindowManager::startDelayedDrag( gpointer data )
    {
        static_cast<WindowManager*>( data )->startDrag();
        return FALSE;
    }

    //_________________________________________________
    bool WindowManager::isWindowDragWidget( GtkWidget* widget, GdkEventButton* event )
    {
        if( _mode == Disabled ) return false;
        else if( (!_drag) && withinWidget(widget, event ) && useEvent( widget, event ) )
        {

            // store widget and event position
            _widget = widget;
            _x = int(event->x_root);
            _y = int(event->y_root);

            // start timer
            if( _timer.isRunning() ) _timer.stop();
            _timer.start( _dragDelay, (GSourceFunc)startDelayedDrag, this );

            // enable drag and accept
            _drag = true;
            return true;

        } else return false;
    }

    //_________________________________________________________________
    bool WindowManager::startDrag( GtkWidget* widget, GdkEventMotion* event )
    {

        // make sure drag is enabled
        if( !_drag ) return false;

        // check displacement with respect to drag start
        const int distance( abs( _x - int(event->x_root) ) + abs( _y - int(event->y_root) ) );

        if( distance > 0 && _timer.isRunning() ) _timer.stop();
        if( distance < _dragDistance ) return false;

        // start drag from current position
        return startDrag( widget, int(event->x_root), int(event->y_root) );

    }

    //_________________________________________________________________
    bool WindowManager::startDrag( GtkWidget* widget, int x, int y )
    {
        // create xevent and send.
        XEvent     xev;
        GtkWindow  *topLevel = GTK_WINDOW( gtk_widget_get_toplevel( widget ) );
        GdkWindow  *window = gtk_widget_get_window( GTK_WIDGET( topLevel ) );
        GdkDisplay *display = gtk_widget_get_display( GTK_WIDGET( topLevel ) );
        GdkWindow  *root = gdk_screen_get_root_window( gtk_window_get_screen( topLevel ) );

        xev.xclient.type = ClientMessage;
        xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display(display, "_NET_WM_MOVERESIZE");
        xev.xclient.display = GDK_DISPLAY_XDISPLAY(display);
        xev.xclient.window = GDK_WINDOW_XID(window);
        xev.xclient.format = 32;
        xev.xclient.data.l[0] = x;
        xev.xclient.data.l[1] = y;
        xev.xclient.data.l[2] = 8; // NET::Move
        xev.xclient.data.l[3] = Button1;
        xev.xclient.data.l[4] = 0;
        XUngrabPointer(GDK_DISPLAY_XDISPLAY(display), CurrentTime);

        XSendEvent(
            GDK_DISPLAY_XDISPLAY(display),
            GDK_WINDOW_XID(root),
            False,
            SubstructureRedirectMask | SubstructureNotifyMask,
            &xev);

        // force a release as some widgets miss it...
        wmButtonRelease( widget, 0L, this );
        return true;
    }

    //_________________________________________________
    bool WindowManager::finishDrag( GtkWidget* widget )
    {

        _widget = 0L;
        _lastRejectedEvent = 0L;
        _x = -1;
        _y = -1;

        if( _drag )
        {

            gtk_grab_remove(widget);
            gdk_pointer_ungrab( CurrentTime );
            _drag = false;
            return true;

        } else return false;

    }

    //_________________________________________________
    bool WindowManager::withinWidget( GtkWidget* widget, GdkEventButton* event ) const
    {

        // get widget window
        GdkWindow *window( gtk_widget_get_window( widget ) );

        // Some widgets aren't realized (GeditWindow for exemple) ...
        if( !window ) return true;

        GtkAllocation allocation;

        if( GTK_IS_NOTEBOOK( widget ) )
        {

            Gtk::gtk_notebook_get_tabbar_rect( GTK_NOTEBOOK( widget ), &allocation );

        } else {

            #if GTK_CHECK_VERSION(2, 18, 0)
            gtk_widget_get_allocation( widget, &allocation );
            #else
            allocation = widget->allocation;
            #endif

        }

        // translate to current window
        int nx(0);
        int ny(0);
        gdk_window_get_geometry( window, &nx, &ny, 0L, 0L, 0L );
        allocation.x -= nx;
        allocation.y -= ny;

        // translate absolute coordinates
        gdk_window_get_origin(window, &nx, &ny );
        allocation.x += nx;
        allocation.y += ny;

        return Gtk::gdk_rectangle_contains( &allocation, int(event->x_root), int(event->y_root) );

    }

    //_________________________________________________
    bool WindowManager::useEvent( GtkWidget* widget, GdkEventButton* event )
    {

        // check against mode
        if( _mode == Disabled ) return false;
        if( _mode == Minimal && !( GTK_IS_TOOLBAR( widget ) || GTK_IS_MENU_BAR( widget ) ) ) return false;
        if( _lastRejectedEvent && event == _lastRejectedEvent ) return false;

        // always accept if widget is not a container
        if( !GTK_IS_CONTAINER( widget ) ) return true;

        // if widget is a notebook, accept if there is no hovered tab
        bool useEvent( true );
        if( GTK_IS_NOTEBOOK( widget ) )
        {

            useEvent =
                ( !Gtk::gtk_notebook_has_visible_arrows( GTK_NOTEBOOK( widget ) ) ) &&
                Style::instance().animations().tabWidgetEngine().contains( widget ) &&
                Style::instance().animations().tabWidgetEngine().hoveredTab( widget ) == -1 &&
                childrenUseEvent( widget, event, false );

        } else {

            useEvent = childrenUseEvent( widget, event, false );

        }

        if( !useEvent ) _lastRejectedEvent = event;
        return useEvent;

    }

    //_________________________________________________
    bool WindowManager::childrenUseEvent( GtkWidget* widget, GdkEventButton* event, bool inNoteBook ) const
    {
        // accept, by default
        bool usable = true;

        // get children and check
        GList *children = gtk_container_get_children( GTK_CONTAINER( widget ) );
        for( GList *child = g_list_first( children ); child && usable ; child = g_list_next( child ) )
        {

            // cast child to GtkWidget
            if( !GTK_IS_WIDGET( child->data ) ) continue;
            GtkWidget* childWidget( GTK_WIDGET( child->data ) );

            // check widget state and type
            if( gtk_widget_get_state( childWidget ) == GTK_STATE_PRELIGHT )
            {

                // if widget is prelight, we don't need to check where event happen,
                // any prelight widget indicate we can't do a move
                usable = false;
                continue;

            }

            GdkWindow *window = gtk_widget_get_window( childWidget );
            if( !( window && gdk_window_is_visible( window ) ) )
            { continue; }

            if( GTK_IS_NOTEBOOK( childWidget ) ) inNoteBook = true;

            if( !( event && withinWidget( childWidget, event ) ) )
            { continue; }

            #if OXYGEN_DEBUG
            std::cout << "Oxygen::WindowManager::childrenUseEvent - "
                << widget
                << "(" << G_OBJECT_TYPE_NAME( childWidget ) << ")"
                << " " << gtk_widget_get_name( childWidget )
                << std::endl;
            #endif

            // check special cases for which grab should not be enabled
            if(
                ( widgetIsBlackListed( childWidget ) ) ||
                ( GTK_IS_NOTEBOOK( widget ) && Gtk::gtk_notebook_is_tab_label( GTK_NOTEBOOK( widget ), childWidget ) ) ||
                ( GTK_IS_BUTTON( childWidget ) && gtk_widget_get_state( childWidget ) != GTK_STATE_INSENSITIVE ) ||
                ( gtk_widget_get_events ( childWidget ) & (GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK) ) ||
                ( GTK_IS_MENU_ITEM( childWidget ) ) ||
                ( GTK_IS_SCROLLED_WINDOW( childWidget ) && ( !inNoteBook || gtk_widget_is_focus( childWidget ) ) ) )
            { usable = false; }

            // if child is a container and event has been accepted so far, also check it, recursively
            if( usable && GTK_IS_CONTAINER( childWidget ) )
            { usable = childrenUseEvent( childWidget, event, inNoteBook); }

        }

        // free list
        if( children ) g_list_free( children );

        return usable;
    }

    //_________________________________________________
    void WindowManager::initializeBlackList( void )
    {
        // clear list
        _blackList.clear();
        _blackList.push_back( "GtkPizza" );
        _blackList.push_back( "MetaFrames" );
        _blackList.push_back( "GladeDesignLayout" );
    }

    //________________________________________________________________________________
    void WindowManager::connect( GtkWidget* widget, WindowManager::Data& data )
    {
        data._destroyId.connect( G_OBJECT( widget ), "destroy", G_CALLBACK( wmDestroy ), this );
        data._styleId.connect( G_OBJECT( widget ), "style-set", G_CALLBACK( wmStyleSet ), this );

        data._pressId.connect( G_OBJECT( widget ), "button-press-event", G_CALLBACK( wmButtonPress ), this );
        data._releaseId.connect( G_OBJECT( widget ), "button-release-event", G_CALLBACK( wmButtonRelease ), this );
        data._leaveId.connect( G_OBJECT( widget ), "leave-notify-event", G_CALLBACK( wmLeave ), this );
        data._motionId.connect( G_OBJECT( widget ), "motion-notify-event", G_CALLBACK( wmMotion ), this );
    }

    //_________________________________________________
    void WindowManager::Data::disconnect( GtkWidget* )
    {

        _leaveId.disconnect();
        _destroyId.disconnect();
        _pressId.disconnect();
        _releaseId.disconnect();
        _motionId.disconnect();
        _styleId.disconnect();

    }

}
<commit_msg>blacklisted SPHRuler and SPVRuler. BUG: 260582<commit_after>/*
* oxygenwindowmanager.cpp
* pass some window mouse press/release/move event actions to window manager
* -------------------
*
* Copyright (c) 2010 Cédric Bellegarde <gnumdk@gmail.com>
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
*
* Largely inspired from Qtcurve style
* Copyright (C) Craig Drummond, 2003 - 2010 craig.p.drummond@gmail.com
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or( at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygenwindowmanager.h"
#include "oxygenstyle.h"
#include "config.h"

#include <gdk/gdkx.h>
namespace Oxygen
{

    //_________________________________________________
    WindowManager::WindowManager( void ):
        _mode( Full ),
        _drag( false ),
        _dragDistance( 4 ),
        _dragDelay( 500 ),
        _widget( 0L ),
        _lastRejectedEvent( 0L ),
        _x(-1),
        _y(-1)
    { initializeBlackList(); }

    //_________________________________________________
    WindowManager::~WindowManager( void )
    {
        _map.disconnectAll();
        _map.clear();
    }

    //_________________________________________________
    void WindowManager::registerWidget( GtkWidget* widget )
    {

        if( _map.contains( widget ) || widgetIsBlackListed( widget ) ) return;

        // Window with no decorations (set by app), let window manage it self
        if( GTK_IS_WINDOW( widget ) && !gtk_window_get_decorated( GTK_WINDOW( widget ) ) ) return;

        // widgets used in tabs also must be ignored (happens, unfortunately)
        GtkWidget* parent( gtk_widget_get_parent( widget ) );
        if( GTK_IS_NOTEBOOK( parent ) && Gtk::gtk_notebook_is_tab_label( GTK_NOTEBOOK( parent ), widget ) )
        { return; }

        #if OXYGEN_DEBUG
        std::cout << "Oxygen::WindowManager::registerWidget - " << widget << "(" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
        #endif

        // Force widget to listen to relevant events
        gtk_widget_add_events( widget,
            GDK_BUTTON_RELEASE_MASK |
            GDK_BUTTON_PRESS_MASK   |
            GDK_LEAVE_NOTIFY_MASK   |
            GDK_BUTTON1_MOTION_MASK );

        // allocate new Data object
        Data& data( _map.registerWidget( widget ) );

        // connect signals
        if( _mode != Disabled ) connect( widget, data );

    }

    //_________________________________________________
    void WindowManager::unregisterWidget( GtkWidget* widget )
    {
        if( !_map.contains( widget ) ) return;

        #if OXYGEN_DEBUG
        std::cout << "Oxygen::WindowManager::unregisterWidget - " << widget << "(" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
        #endif

        _map.value( widget ).disconnect( widget );
        _map.erase( widget );

        if( _widget == widget )
        {
            _widget = 0L;
            _x = -1;
            _y = -1;
            _drag = false;
        }

    }

    //_________________________________________________
    void WindowManager::setMode( WindowManager::Mode mode )
    {
        if( mode == _mode ) return;

        // connect/disconnect all data in map, based on new and old mode
        if( mode == Disabled ) { _map.disconnectAll(); }
        else if( _mode == Disabled )
        {
            DataMap<Data>::Map& map( _map.map() );
            for( DataMap<Data>::Map::iterator iter = map.begin(); iter != map.end(); ++iter )
            { connect( iter->first, iter->second ); }
        }

        // assign new mode
        _mode = mode;

    }

    //_________________________________________________
    gboolean WindowManager::wmStyleSet( GtkWidget* widget, GtkStyle* , gpointer data )
    {
        static_cast<WindowManager*>(data)->unregisterWidget( widget );
        return false;
    }

    //_________________________________________________
    gboolean WindowManager::wmDestroy( GtkWidget* widget, gpointer data )
    {
        static_cast<WindowManager*>(data)->unregisterWidget( widget );
        return false;
    }

    //_________________________________________________
    gboolean WindowManager::wmButtonPress(GtkWidget *widget, GdkEventButton* event, gpointer data )
    {

        if( event->type == GDK_BUTTON_PRESS && event->button == Gtk::LeftButton )
        {

            #if OXYGEN_DEBUG
            std::cout << "Oxygen::WindowManager::wmButtonPress -"
                << " event: " << event
                << " widget: " << widget
                << "(" << G_OBJECT_TYPE_NAME( widget ) << ")"
                << " " << gtk_widget_get_name( widget )
                << std::endl;
            #endif

            return static_cast<WindowManager*>(data)->isWindowDragWidget( widget, event );

        } else return false;

    }

    //_________________________________________________
    gboolean WindowManager::wmButtonRelease(GtkWidget *widget, GdkEventButton*, gpointer data )
    { return static_cast<WindowManager*>( data )->finishDrag( widget ); }

    //_________________________________________________
    gboolean WindowManager::wmLeave(GtkWidget *widget, GdkEventCrossing*, gpointer data )
    { return static_cast<WindowManager*>( data )->finishDrag( widget ); }

    //_________________________________________________
    gboolean WindowManager::wmMotion( GtkWidget *widget, GdkEventMotion* event, gpointer data )
    { return static_cast<WindowManager*>(data)->startDrag( widget, event ); }

    //_________________________________________________________________
    gboolean WindowManager::startDelayedDrag( gpointer data )
    {
        static_cast<WindowManager*>( data )->startDrag();
        return FALSE;
    }

    //_________________________________________________
    bool WindowManager::isWindowDragWidget( GtkWidget* widget, GdkEventButton* event )
    {
        if( _mode == Disabled ) return false;
        else if( (!_drag) && withinWidget(widget, event ) && useEvent( widget, event ) )
        {

            // store widget and event position
            _widget = widget;
            _x = int(event->x_root);
            _y = int(event->y_root);

            // start timer
            if( _timer.isRunning() ) _timer.stop();
            _timer.start( _dragDelay, (GSourceFunc)startDelayedDrag, this );

            // enable drag and accept
            _drag = true;
            return true;

        } else return false;
    }

    //_________________________________________________________________
    bool WindowManager::startDrag( GtkWidget* widget, GdkEventMotion* event )
    {

        // make sure drag is enabled
        if( !_drag ) return false;

        // check displacement with respect to drag start
        const int distance( abs( _x - int(event->x_root) ) + abs( _y - int(event->y_root) ) );

        if( distance > 0 && _timer.isRunning() ) _timer.stop();
        if( distance < _dragDistance ) return false;

        // start drag from current position
        return startDrag( widget, int(event->x_root), int(event->y_root) );

    }

    //_________________________________________________________________
    bool WindowManager::startDrag( GtkWidget* widget, int x, int y )
    {
        // create xevent and send.
        XEvent     xev;
        GtkWindow  *topLevel = GTK_WINDOW( gtk_widget_get_toplevel( widget ) );
        GdkWindow  *window = gtk_widget_get_window( GTK_WIDGET( topLevel ) );
        GdkDisplay *display = gtk_widget_get_display( GTK_WIDGET( topLevel ) );
        GdkWindow  *root = gdk_screen_get_root_window( gtk_window_get_screen( topLevel ) );

        xev.xclient.type = ClientMessage;
        xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display(display, "_NET_WM_MOVERESIZE");
        xev.xclient.display = GDK_DISPLAY_XDISPLAY(display);
        xev.xclient.window = GDK_WINDOW_XID(window);
        xev.xclient.format = 32;
        xev.xclient.data.l[0] = x;
        xev.xclient.data.l[1] = y;
        xev.xclient.data.l[2] = 8; // NET::Move
        xev.xclient.data.l[3] = Button1;
        xev.xclient.data.l[4] = 0;
        XUngrabPointer(GDK_DISPLAY_XDISPLAY(display), CurrentTime);

        XSendEvent(
            GDK_DISPLAY_XDISPLAY(display),
            GDK_WINDOW_XID(root),
            False,
            SubstructureRedirectMask | SubstructureNotifyMask,
            &xev);

        // force a release as some widgets miss it...
        wmButtonRelease( widget, 0L, this );
        return true;
    }

    //_________________________________________________
    bool WindowManager::finishDrag( GtkWidget* widget )
    {

        _widget = 0L;
        _lastRejectedEvent = 0L;
        _x = -1;
        _y = -1;

        if( _drag )
        {

            gtk_grab_remove(widget);
            gdk_pointer_ungrab( CurrentTime );
            _drag = false;
            return true;

        } else return false;

    }

    //_________________________________________________
    bool WindowManager::withinWidget( GtkWidget* widget, GdkEventButton* event ) const
    {

        // get widget window
        GdkWindow *window( gtk_widget_get_window( widget ) );

        // Some widgets aren't realized (GeditWindow for exemple) ...
        if( !window ) return true;

        GtkAllocation allocation;

        if( GTK_IS_NOTEBOOK( widget ) )
        {

            Gtk::gtk_notebook_get_tabbar_rect( GTK_NOTEBOOK( widget ), &allocation );

        } else {

            #if GTK_CHECK_VERSION(2, 18, 0)
            gtk_widget_get_allocation( widget, &allocation );
            #else
            allocation = widget->allocation;
            #endif

        }

        // translate to current window
        int nx(0);
        int ny(0);
        gdk_window_get_geometry( window, &nx, &ny, 0L, 0L, 0L );
        allocation.x -= nx;
        allocation.y -= ny;

        // translate absolute coordinates
        gdk_window_get_origin(window, &nx, &ny );
        allocation.x += nx;
        allocation.y += ny;

        return Gtk::gdk_rectangle_contains( &allocation, int(event->x_root), int(event->y_root) );

    }

    //_________________________________________________
    bool WindowManager::useEvent( GtkWidget* widget, GdkEventButton* event )
    {

        // check against mode
        if( _mode == Disabled ) return false;
        if( _mode == Minimal && !( GTK_IS_TOOLBAR( widget ) || GTK_IS_MENU_BAR( widget ) ) ) return false;
        if( _lastRejectedEvent && event == _lastRejectedEvent ) return false;

        // always accept if widget is not a container
        if( !GTK_IS_CONTAINER( widget ) ) return true;

        // if widget is a notebook, accept if there is no hovered tab
        bool useEvent( true );
        if( GTK_IS_NOTEBOOK( widget ) )
        {

            useEvent =
                ( !Gtk::gtk_notebook_has_visible_arrows( GTK_NOTEBOOK( widget ) ) ) &&
                Style::instance().animations().tabWidgetEngine().contains( widget ) &&
                Style::instance().animations().tabWidgetEngine().hoveredTab( widget ) == -1 &&
                childrenUseEvent( widget, event, false );

        } else {

            useEvent = childrenUseEvent( widget, event, false );

        }

        if( !useEvent ) _lastRejectedEvent = event;
        return useEvent;

    }

    //_________________________________________________
    bool WindowManager::childrenUseEvent( GtkWidget* widget, GdkEventButton* event, bool inNoteBook ) const
    {
        // accept, by default
        bool usable = true;

        // get children and check
        GList *children = gtk_container_get_children( GTK_CONTAINER( widget ) );
        for( GList *child = g_list_first( children ); child && usable ; child = g_list_next( child ) )
        {

            // cast child to GtkWidget
            if( !GTK_IS_WIDGET( child->data ) ) continue;
            GtkWidget* childWidget( GTK_WIDGET( child->data ) );

            // check widget state and type
            if( gtk_widget_get_state( childWidget ) == GTK_STATE_PRELIGHT )
            {

                // if widget is prelight, we don't need to check where event happen,
                // any prelight widget indicate we can't do a move
                usable = false;
                continue;

            }

            GdkWindow *window = gtk_widget_get_window( childWidget );
            if( !( window && gdk_window_is_visible( window ) ) )
            { continue; }

            if( GTK_IS_NOTEBOOK( childWidget ) ) inNoteBook = true;

            if( !( event && withinWidget( childWidget, event ) ) )
            { continue; }

            #if OXYGEN_DEBUG
            std::cout << "Oxygen::WindowManager::childrenUseEvent - "
                << widget
                << "(" << G_OBJECT_TYPE_NAME( childWidget ) << ")"
                << " " << gtk_widget_get_name( childWidget )
                << std::endl;
            #endif

            // check special cases for which grab should not be enabled
            if(
                ( widgetIsBlackListed( childWidget ) ) ||
                ( GTK_IS_NOTEBOOK( widget ) && Gtk::gtk_notebook_is_tab_label( GTK_NOTEBOOK( widget ), childWidget ) ) ||
                ( GTK_IS_BUTTON( childWidget ) && gtk_widget_get_state( childWidget ) != GTK_STATE_INSENSITIVE ) ||
                ( gtk_widget_get_events ( childWidget ) & (GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK) ) ||
                ( GTK_IS_MENU_ITEM( childWidget ) ) ||
                ( GTK_IS_SCROLLED_WINDOW( childWidget ) && ( !inNoteBook || gtk_widget_is_focus( childWidget ) ) ) )
            { usable = false; }

            // if child is a container and event has been accepted so far, also check it, recursively
            if( usable && GTK_IS_CONTAINER( childWidget ) )
            { usable = childrenUseEvent( childWidget, event, inNoteBook); }

        }

        // free list
        if( children ) g_list_free( children );

        return usable;
    }

    //_________________________________________________
    void WindowManager::initializeBlackList( void )
    {
        // clear list
        _blackList.clear();
        _blackList.push_back( "GtkPizza" );
        _blackList.push_back( "MetaFrames" );
        _blackList.push_back( "GladeDesignLayout" );
        _blackList.push_back( "SPHRuler" );
        _blackList.push_back( "SPVRuler" );
    }

    //________________________________________________________________________________
    void WindowManager::connect( GtkWidget* widget, WindowManager::Data& data )
    {
        data._destroyId.connect( G_OBJECT( widget ), "destroy", G_CALLBACK( wmDestroy ), this );
        data._styleId.connect( G_OBJECT( widget ), "style-set", G_CALLBACK( wmStyleSet ), this );

        data._pressId.connect( G_OBJECT( widget ), "button-press-event", G_CALLBACK( wmButtonPress ), this );
        data._releaseId.connect( G_OBJECT( widget ), "button-release-event", G_CALLBACK( wmButtonRelease ), this );
        data._leaveId.connect( G_OBJECT( widget ), "leave-notify-event", G_CALLBACK( wmLeave ), this );
        data._motionId.connect( G_OBJECT( widget ), "motion-notify-event", G_CALLBACK( wmMotion ), this );
    }

    //_________________________________________________
    void WindowManager::Data::disconnect( GtkWidget* )
    {

        _leaveId.disconnect();
        _destroyId.disconnect();
        _pressId.disconnect();
        _releaseId.disconnect();
        _motionId.disconnect();
        _styleId.disconnect();

    }

}
<|endoftext|>


<commit_before>#include "moses/FF/Factory.h"
#include "moses/StaticData.h"

#include "moses/TranslationModel/PhraseDictionaryTreeAdaptor.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryOnDisk.h"
#include "moses/TranslationModel/PhraseDictionaryMemory.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModel.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModelCounts.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryALSuffixArray.h"
#include "moses/TranslationModel/PhraseDictionaryDynSuffixArray.h"
#include "moses/TranslationModel/PhraseDictionaryScope3.h"
#include "moses/TranslationModel/PhraseDictionaryTransliteration.h"

#include "moses/FF/LexicalReordering/LexicalReordering.h"

#include "moses/FF/BleuScoreFeature.h"
#include "moses/FF/TargetWordInsertionFeature.h"
#include "moses/FF/SourceWordDeletionFeature.h"
#include "moses/FF/GlobalLexicalModel.h"
#include "moses/FF/GlobalLexicalModelUnlimited.h"
#include "moses/FF/UnknownWordPenaltyProducer.h"
#include "moses/FF/WordTranslationFeature.h"
#include "moses/FF/TargetBigramFeature.h"
#include "moses/FF/TargetNgramFeature.h"
#include "moses/FF/PhraseBoundaryFeature.h"
#include "moses/FF/PhrasePairFeature.h"
#include "moses/FF/PhraseLengthFeature.h"
#include "moses/FF/DistortionScoreProducer.h"
#include "moses/FF/WordPenaltyProducer.h"
#include "moses/FF/InputFeature.h"
#include "moses/FF/PhrasePenalty.h"
#include "moses/FF/OSM-Feature/OpSequenceModel.h"
#include "moses/FF/ControlRecombination.h"
#include "moses/FF/ExternalFeature.h"
#include "moses/FF/ConstrainedDecoding.h"
#include "moses/FF/CoveredReferenceFeature.h"
#include "moses/FF/TreeStructureFeature.h"
#include "moses/FF/SoftMatchingFeature.h"
#include "moses/FF/SourceGHKMTreeInputMatchFeature.h"
#include "moses/FF/HyperParameterAsWeight.h"
#include "moses/FF/SetSourcePhrase.h"
#include "CountNonTerms.h"
#include "ReferenceComparison.h"
#include "RuleScope.h"
#include "MaxSpanFreeNonTermSource.h"
#include "NieceTerminal.h"
#include "SpanLength.h"
#include "SyntaxRHS.h"

#include "moses/FF/SkeletonStatelessFF.h"
#include "moses/FF/SkeletonStatefulFF.h"
#include "moses/LM/SkeletonLM.h"
#include "moses/TranslationModel/SkeletonPT.h"

#ifdef HAVE_CMPH
#include "moses/TranslationModel/CompactPT/PhraseDictionaryCompact.h"
#endif
#ifdef PT_UG
#include "moses/TranslationModel/UG/mmsapt.h"
#endif
#ifdef HAVE_PROBINGPT
#include "moses/TranslationModel/ProbingPT/ProbingPT.h"
#endif

#include "moses/LM/Ken.h"
#ifdef LM_IRST
#include "moses/LM/IRST.h"
#endif

#ifdef LM_SRI
#include "moses/LM/SRI.h"
#endif

#ifdef LM_MAXENT_SRI
#include "moses/LM/MaxEntSRI.h"
#endif

#ifdef LM_RAND
#include "moses/LM/Rand.h"
#endif

#ifdef HAVE_SYNLM
#include "moses/SyntacticLanguageModel.h"
#endif

#ifdef LM_NEURAL
#include "moses/LM/NeuralLMWrapper.h"
#endif

#ifdef LM_DALM
#include "moses/LM/DALMWrapper.h"
#endif

#include "util/exception.hh"

#include <vector>

namespace Moses
{

class FeatureFactory
{
public:
  virtual ~FeatureFactory() {}

  virtual void Create(const std::string &line) = 0;

protected:
  template <class F> static void DefaultSetup(F *feature);

  FeatureFactory() {}
};

template <class F> void FeatureFactory::DefaultSetup(F *feature)
{
  StaticData &static_data = StaticData::InstanceNonConst();
  const string &featureName = feature->GetScoreProducerDescription();
  std::vector<float> weights = static_data.GetParameter()->GetWeights(featureName);

  if (feature->IsTuneable() || weights.size()) {
    // if it's tuneable, ini file MUST have weights
    // even it it's not tuneable, people can still set the weights in the ini file
    static_data.SetWeights(feature, weights);
  } else if (feature->GetNumScoreComponents() > 0) {
    std::vector<float> defaultWeights = feature->DefaultWeights();
    static_data.SetWeights(feature, defaultWeights);
  }
}

namespace
{

template <class F> class DefaultFeatureFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(new F(line));
  }
};

class KenFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(ConstructKenLM(line));
  }
};

} // namespace

FeatureRegistry::FeatureRegistry()
{
// Feature with same name as class
#define MOSES_FNAME(name) Add(#name, new DefaultFeatureFactory< name >());
// Feature with different name than class.
#define MOSES_FNAME2(name, type) Add(name, new DefaultFeatureFactory< type >());
  MOSES_FNAME(GlobalLexicalModel);
  //MOSES_FNAME(GlobalLexicalModelUnlimited); This was commented out in the original
  MOSES_FNAME(SourceWordDeletionFeature);
  MOSES_FNAME(TargetWordInsertionFeature);
  MOSES_FNAME(PhraseBoundaryFeature);
  MOSES_FNAME(PhraseLengthFeature);
  MOSES_FNAME(WordTranslationFeature);
  MOSES_FNAME(TargetBigramFeature);
  MOSES_FNAME(TargetNgramFeature);
  MOSES_FNAME(PhrasePairFeature);
  MOSES_FNAME(LexicalReordering);
  MOSES_FNAME2("Generation", GenerationDictionary);
  MOSES_FNAME(BleuScoreFeature);
  MOSES_FNAME2("Distortion", DistortionScoreProducer);
  MOSES_FNAME2("WordPenalty", WordPenaltyProducer);
  MOSES_FNAME(InputFeature);
  MOSES_FNAME2("PhraseDictionaryBinary", PhraseDictionaryTreeAdaptor);
  MOSES_FNAME(PhraseDictionaryOnDisk);
  MOSES_FNAME(PhraseDictionaryMemory);
  MOSES_FNAME(PhraseDictionaryScope3);
  MOSES_FNAME(PhraseDictionaryMultiModel);
  MOSES_FNAME(PhraseDictionaryMultiModelCounts);
  MOSES_FNAME(PhraseDictionaryALSuffixArray);
  MOSES_FNAME(PhraseDictionaryDynSuffixArray);
  MOSES_FNAME(PhraseDictionaryTransliteration);
  MOSES_FNAME(OpSequenceModel);
  MOSES_FNAME(PhrasePenalty);
  MOSES_FNAME2("UnknownWordPenalty", UnknownWordPenaltyProducer);
  MOSES_FNAME(ControlRecombination);
  MOSES_FNAME(ConstrainedDecoding);
  MOSES_FNAME(CoveredReferenceFeature);
  MOSES_FNAME(ExternalFeature);
  MOSES_FNAME(SourceGHKMTreeInputMatchFeature);
  MOSES_FNAME(TreeStructureFeature);
  MOSES_FNAME(SoftMatchingFeature);
  MOSES_FNAME(HyperParameterAsWeight);
  MOSES_FNAME(SetSourcePhrase);
  MOSES_FNAME(CountNonTerms);
  MOSES_FNAME(ReferenceComparison);
  MOSES_FNAME(RuleScope);
  MOSES_FNAME(MaxSpanFreeNonTermSource);
  MOSES_FNAME(NieceTerminal);
  MOSES_FNAME(SpanLength);
  MOSES_FNAME(SyntaxRHS);

  MOSES_FNAME(SkeletonStatelessFF);
  MOSES_FNAME(SkeletonStatefulFF);
  MOSES_FNAME(SkeletonLM);
  MOSES_FNAME(SkeletonPT);

#ifdef HAVE_CMPH
  MOSES_FNAME(PhraseDictionaryCompact);
#endif
#ifdef PT_UG
  MOSES_FNAME(Mmsapt);
#endif
#ifdef HAVE_PROBINGPT
  MOSES_FNAME(ProbingPT);
#endif

#ifdef HAVE_SYNLM
  MOSES_FNAME(SyntacticLanguageModel);
#endif
#ifdef LM_IRST
  MOSES_FNAME2("IRSTLM", LanguageModelIRST);
#endif
#ifdef LM_SRI
  MOSES_FNAME2("SRILM", LanguageModelSRI);
#endif
#ifdef LM_MAXENT_SRI
  MOSES_FNAME2("MaxEntLM", LanguageModelMaxEntSRI);
#endif
#ifdef LM_RAND
  MOSES_FNAME2("RANDLM", LanguageModelRandLM);
#endif
#ifdef LM_NEURAL
  MOSES_FNAME2("NeuralLM", NeuralLMWrapper);
#endif
#ifdef LM_DALM
  MOSES_FNAME2("DALM", LanguageModelDALM);
#endif

  Add("KENLM", new KenFactory());
}

FeatureRegistry::~FeatureRegistry()
{
}

void FeatureRegistry::Add(const std::string &name, FeatureFactory *factory)
{
  std::pair<std::string, boost::shared_ptr<FeatureFactory> > to_ins(name, boost::shared_ptr<FeatureFactory>(factory));
  UTIL_THROW_IF2(!registry_.insert(to_ins).second, "Duplicate feature name " << name);
}

namespace
{
class UnknownFeatureException : public util::Exception {};
}

void FeatureRegistry::Construct(const std::string &name, const std::string &line)
{
  Map::iterator i = registry_.find(name);
  UTIL_THROW_IF(i == registry_.end(), UnknownFeatureException, "Feature name " << name << " is not registered.");
  i->second->Create(line);
}

void FeatureRegistry::PrintFF() const
{
	std::cerr << "Available feature functions:" << std::endl;
	Map::const_iterator iter;
	for (iter = registry_.begin(); iter != registry_.end(); ++iter) {
		const string &ffName = iter->first;
		std::cerr << ffName << " ";
	}
	std::cerr << std::endl;
}

} // namespace Moses
<commit_msg>register PhraseDictionaryFuzzyMatch<commit_after>#include "moses/FF/Factory.h"
#include "moses/StaticData.h"

#include "moses/TranslationModel/PhraseDictionaryTreeAdaptor.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryOnDisk.h"
#include "moses/TranslationModel/PhraseDictionaryMemory.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModel.h"
#include "moses/TranslationModel/PhraseDictionaryMultiModelCounts.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryALSuffixArray.h"
#include "moses/TranslationModel/PhraseDictionaryDynSuffixArray.h"
#include "moses/TranslationModel/PhraseDictionaryScope3.h"
#include "moses/TranslationModel/PhraseDictionaryTransliteration.h"
#include "moses/TranslationModel/RuleTable/PhraseDictionaryFuzzyMatch.h"

#include "moses/FF/LexicalReordering/LexicalReordering.h"

#include "moses/FF/BleuScoreFeature.h"
#include "moses/FF/TargetWordInsertionFeature.h"
#include "moses/FF/SourceWordDeletionFeature.h"
#include "moses/FF/GlobalLexicalModel.h"
#include "moses/FF/GlobalLexicalModelUnlimited.h"
#include "moses/FF/UnknownWordPenaltyProducer.h"
#include "moses/FF/WordTranslationFeature.h"
#include "moses/FF/TargetBigramFeature.h"
#include "moses/FF/TargetNgramFeature.h"
#include "moses/FF/PhraseBoundaryFeature.h"
#include "moses/FF/PhrasePairFeature.h"
#include "moses/FF/PhraseLengthFeature.h"
#include "moses/FF/DistortionScoreProducer.h"
#include "moses/FF/WordPenaltyProducer.h"
#include "moses/FF/InputFeature.h"
#include "moses/FF/PhrasePenalty.h"
#include "moses/FF/OSM-Feature/OpSequenceModel.h"
#include "moses/FF/ControlRecombination.h"
#include "moses/FF/ExternalFeature.h"
#include "moses/FF/ConstrainedDecoding.h"
#include "moses/FF/CoveredReferenceFeature.h"
#include "moses/FF/TreeStructureFeature.h"
#include "moses/FF/SoftMatchingFeature.h"
#include "moses/FF/SourceGHKMTreeInputMatchFeature.h"
#include "moses/FF/HyperParameterAsWeight.h"
#include "moses/FF/SetSourcePhrase.h"
#include "CountNonTerms.h"
#include "ReferenceComparison.h"
#include "RuleScope.h"
#include "MaxSpanFreeNonTermSource.h"
#include "NieceTerminal.h"
#include "SpanLength.h"
#include "SyntaxRHS.h"

#include "moses/FF/SkeletonStatelessFF.h"
#include "moses/FF/SkeletonStatefulFF.h"
#include "moses/LM/SkeletonLM.h"
#include "moses/TranslationModel/SkeletonPT.h"

#ifdef HAVE_CMPH
#include "moses/TranslationModel/CompactPT/PhraseDictionaryCompact.h"
#endif
#ifdef PT_UG
#include "moses/TranslationModel/UG/mmsapt.h"
#endif
#ifdef HAVE_PROBINGPT
#include "moses/TranslationModel/ProbingPT/ProbingPT.h"
#endif

#include "moses/LM/Ken.h"
#ifdef LM_IRST
#include "moses/LM/IRST.h"
#endif

#ifdef LM_SRI
#include "moses/LM/SRI.h"
#endif

#ifdef LM_MAXENT_SRI
#include "moses/LM/MaxEntSRI.h"
#endif

#ifdef LM_RAND
#include "moses/LM/Rand.h"
#endif

#ifdef HAVE_SYNLM
#include "moses/SyntacticLanguageModel.h"
#endif

#ifdef LM_NEURAL
#include "moses/LM/NeuralLMWrapper.h"
#endif

#ifdef LM_DALM
#include "moses/LM/DALMWrapper.h"
#endif

#include "util/exception.hh"

#include <vector>

namespace Moses
{

class FeatureFactory
{
public:
  virtual ~FeatureFactory() {}

  virtual void Create(const std::string &line) = 0;

protected:
  template <class F> static void DefaultSetup(F *feature);

  FeatureFactory() {}
};

template <class F> void FeatureFactory::DefaultSetup(F *feature)
{
  StaticData &static_data = StaticData::InstanceNonConst();
  const string &featureName = feature->GetScoreProducerDescription();
  std::vector<float> weights = static_data.GetParameter()->GetWeights(featureName);

  if (feature->IsTuneable() || weights.size()) {
    // if it's tuneable, ini file MUST have weights
    // even it it's not tuneable, people can still set the weights in the ini file
    static_data.SetWeights(feature, weights);
  } else if (feature->GetNumScoreComponents() > 0) {
    std::vector<float> defaultWeights = feature->DefaultWeights();
    static_data.SetWeights(feature, defaultWeights);
  }
}

namespace
{

template <class F> class DefaultFeatureFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(new F(line));
  }
};

class KenFactory : public FeatureFactory
{
public:
  void Create(const std::string &line) {
    DefaultSetup(ConstructKenLM(line));
  }
};

} // namespace

FeatureRegistry::FeatureRegistry()
{
// Feature with same name as class
#define MOSES_FNAME(name) Add(#name, new DefaultFeatureFactory< name >());
// Feature with different name than class.
#define MOSES_FNAME2(name, type) Add(name, new DefaultFeatureFactory< type >());

  MOSES_FNAME2("PhraseDictionaryBinary", PhraseDictionaryTreeAdaptor);
  MOSES_FNAME(PhraseDictionaryOnDisk);
  MOSES_FNAME(PhraseDictionaryMemory);
  MOSES_FNAME(PhraseDictionaryScope3);
  MOSES_FNAME(PhraseDictionaryMultiModel);
  MOSES_FNAME(PhraseDictionaryMultiModelCounts);
  MOSES_FNAME(PhraseDictionaryALSuffixArray);
  MOSES_FNAME(PhraseDictionaryDynSuffixArray);
  MOSES_FNAME(PhraseDictionaryTransliteration);
  MOSES_FNAME(PhraseDictionaryFuzzyMatch);

  MOSES_FNAME(GlobalLexicalModel);
  //MOSES_FNAME(GlobalLexicalModelUnlimited); This was commented out in the original
  MOSES_FNAME(SourceWordDeletionFeature);
  MOSES_FNAME(TargetWordInsertionFeature);
  MOSES_FNAME(PhraseBoundaryFeature);
  MOSES_FNAME(PhraseLengthFeature);
  MOSES_FNAME(WordTranslationFeature);
  MOSES_FNAME(TargetBigramFeature);
  MOSES_FNAME(TargetNgramFeature);
  MOSES_FNAME(PhrasePairFeature);
  MOSES_FNAME(LexicalReordering);
  MOSES_FNAME2("Generation", GenerationDictionary);
  MOSES_FNAME(BleuScoreFeature);
  MOSES_FNAME2("Distortion", DistortionScoreProducer);
  MOSES_FNAME2("WordPenalty", WordPenaltyProducer);
  MOSES_FNAME(InputFeature);
  MOSES_FNAME(OpSequenceModel);
  MOSES_FNAME(PhrasePenalty);
  MOSES_FNAME2("UnknownWordPenalty", UnknownWordPenaltyProducer);
  MOSES_FNAME(ControlRecombination);
  MOSES_FNAME(ConstrainedDecoding);
  MOSES_FNAME(CoveredReferenceFeature);
  MOSES_FNAME(ExternalFeature);
  MOSES_FNAME(SourceGHKMTreeInputMatchFeature);
  MOSES_FNAME(TreeStructureFeature);
  MOSES_FNAME(SoftMatchingFeature);
  MOSES_FNAME(HyperParameterAsWeight);
  MOSES_FNAME(SetSourcePhrase);
  MOSES_FNAME(CountNonTerms);
  MOSES_FNAME(ReferenceComparison);
  MOSES_FNAME(RuleScope);
  MOSES_FNAME(MaxSpanFreeNonTermSource);
  MOSES_FNAME(NieceTerminal);
  MOSES_FNAME(SpanLength);
  MOSES_FNAME(SyntaxRHS);

  MOSES_FNAME(SkeletonStatelessFF);
  MOSES_FNAME(SkeletonStatefulFF);
  MOSES_FNAME(SkeletonLM);
  MOSES_FNAME(SkeletonPT);

#ifdef HAVE_CMPH
  MOSES_FNAME(PhraseDictionaryCompact);
#endif
#ifdef PT_UG
  MOSES_FNAME(Mmsapt);
#endif
#ifdef HAVE_PROBINGPT
  MOSES_FNAME(ProbingPT);
#endif

#ifdef HAVE_SYNLM
  MOSES_FNAME(SyntacticLanguageModel);
#endif
#ifdef LM_IRST
  MOSES_FNAME2("IRSTLM", LanguageModelIRST);
#endif
#ifdef LM_SRI
  MOSES_FNAME2("SRILM", LanguageModelSRI);
#endif
#ifdef LM_MAXENT_SRI
  MOSES_FNAME2("MaxEntLM", LanguageModelMaxEntSRI);
#endif
#ifdef LM_RAND
  MOSES_FNAME2("RANDLM", LanguageModelRandLM);
#endif
#ifdef LM_NEURAL
  MOSES_FNAME2("NeuralLM", NeuralLMWrapper);
#endif
#ifdef LM_DALM
  MOSES_FNAME2("DALM", LanguageModelDALM);
#endif

  Add("KENLM", new KenFactory());
}

FeatureRegistry::~FeatureRegistry()
{
}

void FeatureRegistry::Add(const std::string &name, FeatureFactory *factory)
{
  std::pair<std::string, boost::shared_ptr<FeatureFactory> > to_ins(name, boost::shared_ptr<FeatureFactory>(factory));
  UTIL_THROW_IF2(!registry_.insert(to_ins).second, "Duplicate feature name " << name);
}

namespace
{
class UnknownFeatureException : public util::Exception {};
}

void FeatureRegistry::Construct(const std::string &name, const std::string &line)
{
  Map::iterator i = registry_.find(name);
  UTIL_THROW_IF(i == registry_.end(), UnknownFeatureException, "Feature name " << name << " is not registered.");
  i->second->Create(line);
}

void FeatureRegistry::PrintFF() const
{
	std::cerr << "Available feature functions:" << std::endl;
	Map::const_iterator iter;
	for (iter = registry_.begin(); iter != registry_.end(); ++iter) {
		const string &ffName = iter->first;
		std::cerr << ffName << " ";
	}
	std::cerr << std::endl;
}

} // namespace Moses
<|endoftext|>