<commit_before>#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <string>

#include <glimac/glm.hpp>
#include <glimac/SDLWindowManager.hpp>
#include <glimac/Sphere.hpp>

#include <GL/glew.h>

#include "engine/model.hpp"
#include "engine/mesh.hpp"
#include "engine/shader.hpp"
#include "engine/freefly.hpp"
#include "engine/mouse.hpp"

// -------- NAMESPACE -------------- //

using namespace glm;
using namespace std;
using namespace glimac;

// TODO Ajouter ici l'initialisation de la caméra de Chamse

map<string, unique_ptr<Model> > modelsFromFile(string filepath){
    ifstream myFile; //creation du ifstream qui contiendra les données du fichier
    myFile.open(filepath); //ouverture du fichier où sont contenus toutes les infos des modeles (une ligne, un model)
    map<string, unique_ptr<Model> > models;
    if (myFile.is_open()) {
        string path, line; //path est une variable temporaire
        float tx, ty, tz, sx, sy, sz;
        while(getline(myFile, line)){ //tant qu'il existe une ligne après celle-ci{
            istringstream lineStream(line); //on prend les données de la ligne suivante
            lineStream >> path >> tx >> ty >> tz >> sx >> sy >> sz; //on rentre les données de la ligne dans les différentes variables temporaires
            models[path].reset(new Model(path, tx, ty, tz, sx, sy, sz));
        }
    }
    myFile.close();
    return models;
}

int main(int argc, char** argv){

    // -------- GLOBAL VARIABLE -------------- //

    GLuint screenWidth = 1920;
    GLuint screenHeight = 1080;

    //Initialisation de la fenêtre
    SDLWindowManager windowManager(screenWidth, screenHeight, "TEST ASSIMP");

    //TEST SUR GLEW
    GLenum glewInitError = glewInit();
    if(GLEW_OK != glewInitError) {
        std::cerr << glewGetErrorString(glewInitError) << std::endl;
        return EXIT_FAILURE;
    }

    //Affichage des versions Software
    std::cout << "OpenGL Version : " << glGetString(GL_VERSION) << std::endl;
    std::cout << "GLEW Version : " << glewGetString(GLEW_VERSION) << std::endl;

    // Initialisation de GLEW
    glewExperimental = GL_TRUE;
    glewInit();
    glViewport(0, 0, screenWidth, screenHeight);
    glEnable(GL_DEPTH_TEST);

    // Initialisation de la Caméra freefly

    Camera camera = Camera();
    mat4 viewMatrix;

    // Initialisation de l'objet Mouse

    Mouse mouse;

    //Load & Compile Shader
    Shader shader("shaders/model_loading.vs","shaders/model_loading.frag");

    //Load a list of ModelMatrix from a text file
    ///////////////
   map<string, unique_ptr<Model> > models = modelsFromFile("files/assets/models/models.txt");

    //////////////                                                                                //Fermeture du fichier

    //Create the models with the path, translate and scale matrix
    Model& nanosuit = *models["nanosuit.obj"];
    Model& stormtrooper = *models["stormtrooper.obj"];

    int loop = true;
    float xOffset, yOffset;

    while(loop){
        // Event loop:
        SDL_Event e;
        while(windowManager.pollEvent(e)) {
            if(e.type == SDL_QUIT) {
                loop = false; // Leave the loop after this iteration
            }
        }
        //glClear
        glClearColor(0.05f, 0.05f, 0.05f, 1.0f),
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //Lancement des shaders
        shader.Use();
        // ---------------------------- RECUPERATION DES EVENTS CLAVIER / UPDATE CAMERA
        xOffset = windowManager.getMousePosition().x - mouse.lastX - 960;
        yOffset = windowManager.getMousePosition().y - mouse.lastY - 540;

        mouse.lastX = windowManager.getMousePosition().x - 960;
        mouse.lastY = windowManager.getMousePosition().y - 540;

        camera.ProcessMouseMovement(xOffset,yOffset);

        if(windowManager.isKeyPressed(SDLK_z))
            camera.MoveFront(0.010);
        if(windowManager.isKeyPressed(SDLK_q))
            camera.MoveRight(-0.010);
        if(windowManager.isKeyPressed(SDLK_s))
            camera.MoveFront(-0.010);
        if(windowManager.isKeyPressed(SDLK_d))
            camera.MoveRight(0.010);
        if(windowManager.isKeyPressed(SDLK_SPACE))
            camera.MoveUp(0.010);
        if(windowManager.isKeyPressed(SDLK_LSHIFT))
            camera.MoveUp(-0.010);

        // RECUPERATION DE LA SOURIS / UPDATE CAMERA

        // ---------------------------- FIN RECUPERATION EVENTS

        //ENVOIE DES MATRICES

        //Récupération de la viewMatrix de la Caméra

        viewMatrix = camera.GetViewMatrix();

        // Transformation matrices
        glm::mat4 projection = glm::perspective(70.0f, (float)screenWidth/(float)screenHeight, 0.1f, 100.0f);
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(viewMatrix));

        // Draw the loaded model
        glm::mat4 model;
        model = nanosuit.getModelMatrix(); // Translate it down a bit so it's at the center of the scene. It's a bit too big for our scene, so scale it down too. We get the modelmatrix from the attribute. It is a translation*rotation matrix
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
        nanosuit.Draw(shader);

        model = stormtrooper.getModelMatrix();
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
        stormtrooper.Draw(shader);

        // Update the display
        windowManager.swapBuffers();
    }

    return EXIT_SUCCESS;
}
<commit_msg>LITTLE CHANGES IN UNIQUE_PTR FOR MODELS FRM FILE<commit_after>#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <string>

#include <glimac/glm.hpp>
#include <glimac/SDLWindowManager.hpp>
#include <glimac/Sphere.hpp>

#include <GL/glew.h>

#include "engine/model.hpp"
#include "engine/mesh.hpp"
#include "engine/shader.hpp"
#include "engine/freefly.hpp"
#include "engine/mouse.hpp"

// -------- NAMESPACE -------------- //

using namespace glm;
using namespace std;
using namespace glimac;

// TODO Ajouter ici l'initialisation de la caméra de Chamse

map<string, unique_ptr<Model> > modelsFromFile(string filepath){
    ifstream myFile; //creation du ifstream qui contiendra les données du fichier
    myFile.open(filepath); //ouverture du fichier où sont contenus toutes les infos des modeles (une ligne, un model)
    map<string, unique_ptr<Model> > models;
    if (myFile.is_open()) {
        string path, line; //path est une variable temporaire
        float tx, ty, tz, sx, sy, sz;
        while(getline(myFile, line)){ //tant qu'il existe une ligne après celle-ci{
            istringstream lineStream(line); //on prend les données de la ligne suivante
            lineStream >> path >> tx >> ty >> tz >> sx >> sy >> sz; //on rentre les données de la ligne dans les différentes variables temporaires
            models[path].make_unique(new Model(path, tx, ty, tz, sx, sy, sz));
        }
    }
    myFile.close();
    return models;
}

int main(int argc, char** argv){

    // -------- GLOBAL VARIABLE -------------- //

    GLuint screenWidth = 1920;
    GLuint screenHeight = 1080;

    //Initialisation de la fenêtre
    SDLWindowManager windowManager(screenWidth, screenHeight, "TEST ASSIMP");

    //TEST SUR GLEW
    GLenum glewInitError = glewInit();
    if(GLEW_OK != glewInitError) {
        std::cerr << glewGetErrorString(glewInitError) << std::endl;
        return EXIT_FAILURE;
    }

    //Affichage des versions Software
    std::cout << "OpenGL Version : " << glGetString(GL_VERSION) << std::endl;
    std::cout << "GLEW Version : " << glewGetString(GLEW_VERSION) << std::endl;

    // Initialisation de GLEW
    glewExperimental = GL_TRUE;
    glewInit();
    glViewport(0, 0, screenWidth, screenHeight);
    glEnable(GL_DEPTH_TEST);

    // Initialisation de la Caméra freefly

    Camera camera = Camera();
    mat4 viewMatrix;

    // Initialisation de l'objet Mouse

    Mouse mouse;

    //Load & Compile Shader
    Shader shader("shaders/model_loading.vs","shaders/model_loading.frag");

    //Load a list of ModelMatrix from a text file
    ///////////////
   map<string, unique_ptr<Model> > models = modelsFromFile("files/assets/models/models.txt");

    //////////////                                                                                //Fermeture du fichier

    //Create the models with the path, translate and scale matrix
    auto nanosuit = models["nanosuit.obj"];
    auto stormtrooper = models["stormtrooper.obj"];

    int loop = true;
    float xOffset, yOffset;

    while(loop){
        // Event loop:
        SDL_Event e;
        while(windowManager.pollEvent(e)) {
            if(e.type == SDL_QUIT) {
                loop = false; // Leave the loop after this iteration
            }
        }
        //glClear
        glClearColor(0.05f, 0.05f, 0.05f, 1.0f),
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //Lancement des shaders
        shader.Use();
        // ---------------------------- RECUPERATION DES EVENTS CLAVIER / UPDATE CAMERA
        xOffset = windowManager.getMousePosition().x - mouse.lastX - 960;
        yOffset = windowManager.getMousePosition().y - mouse.lastY - 540;

        mouse.lastX = windowManager.getMousePosition().x - 960;
        mouse.lastY = windowManager.getMousePosition().y - 540;

        camera.ProcessMouseMovement(xOffset,yOffset);

        if(windowManager.isKeyPressed(SDLK_z))
            camera.MoveFront(0.010);
        if(windowManager.isKeyPressed(SDLK_q))
            camera.MoveRight(-0.010);
        if(windowManager.isKeyPressed(SDLK_s))
            camera.MoveFront(-0.010);
        if(windowManager.isKeyPressed(SDLK_d))
            camera.MoveRight(0.010);
        if(windowManager.isKeyPressed(SDLK_SPACE))
            camera.MoveUp(0.010);
        if(windowManager.isKeyPressed(SDLK_LSHIFT))
            camera.MoveUp(-0.010);

        // RECUPERATION DE LA SOURIS / UPDATE CAMERA

        // ---------------------------- FIN RECUPERATION EVENTS

        //ENVOIE DES MATRICES

        //Récupération de la viewMatrix de la Caméra

        viewMatrix = camera.GetViewMatrix();

        // Transformation matrices
        glm::mat4 projection = glm::perspective(70.0f, (float)screenWidth/(float)screenHeight, 0.1f, 100.0f);
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(viewMatrix));

        // Draw the loaded model
        glm::mat4 model;
        model = nanosuit->getModelMatrix(); // Translate it down a bit so it's at the center of the scene. It's a bit too big for our scene, so scale it down too. We get the modelmatrix from the attribute. It is a translation*rotation matrix
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
        nanosuit.Draw(shader);

        model = stormtrooper->getModelMatrix();
        glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
        stormtrooper.Draw(shader);

        // Update the display
        windowManager.swapBuffers();
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "vulkan/ShaderModule.h"
#include "vulkan/StructDefs.h"

using namespace Framework::Vulkan;

CShaderModule::CShaderModule(CDevice& device, Framework::CStream& stream)
: m_device(&device)
{
	Create(stream);
}

CShaderModule::~CShaderModule()
{
	Reset();
}

bool CShaderModule::IsEmpty() const
{
	return (m_handle == VK_NULL_HANDLE);
}

void CShaderModule::Reset()
{
	if(m_handle != VK_NULL_HANDLE)
	{
		assert(m_device != nullptr);
		m_device->vkDestroyShaderModule(*m_device, m_handle, nullptr);
		m_device = nullptr;
		m_handle = VK_NULL_HANDLE;
	}
}

CShaderModule& CShaderModule::operator =(CShaderModule&& rhs)
{
	Reset();
	MoveFrom(std::move(rhs));
}

CShaderModule::operator VkShaderModule() const
{
	return m_handle;
}

void CShaderModule::Create(Framework::CStream& stream)
{
	auto shaderLength = stream.GetLength();
	assert((shaderLength & 0x03) == 0);
	uint32* shader = new uint32[shaderLength / 4];
	stream.Read(shader, shaderLength);

	auto shaderModuleCreateInfo = Framework::Vulkan::ShaderModuleCreateInfo();
	shaderModuleCreateInfo.codeSize = shaderLength;
	shaderModuleCreateInfo.pCode    = shader;

	auto result = m_device->vkCreateShaderModule(*m_device, &shaderModuleCreateInfo, nullptr, &m_handle);
	CHECKVULKANERROR(result);

	delete [] shader;
}

void CShaderModule::MoveFrom(CShaderModule&& rhs)
{
	std::swap(m_device, rhs.m_device);
	std::swap(m_handle, rhs.m_handle);
}
<commit_msg>Add missing return value.<commit_after>#include "vulkan/ShaderModule.h"
#include "vulkan/StructDefs.h"

using namespace Framework::Vulkan;

CShaderModule::CShaderModule(CDevice& device, Framework::CStream& stream)
: m_device(&device)
{
	Create(stream);
}

CShaderModule::~CShaderModule()
{
	Reset();
}

bool CShaderModule::IsEmpty() const
{
	return (m_handle == VK_NULL_HANDLE);
}

void CShaderModule::Reset()
{
	if(m_handle != VK_NULL_HANDLE)
	{
		assert(m_device != nullptr);
		m_device->vkDestroyShaderModule(*m_device, m_handle, nullptr);
		m_device = nullptr;
		m_handle = VK_NULL_HANDLE;
	}
}

CShaderModule& CShaderModule::operator =(CShaderModule&& rhs)
{
	Reset();
	MoveFrom(std::move(rhs));
	return (*this);
}

CShaderModule::operator VkShaderModule() const
{
	return m_handle;
}

void CShaderModule::Create(Framework::CStream& stream)
{
	auto shaderLength = stream.GetLength();
	assert((shaderLength & 0x03) == 0);
	uint32* shader = new uint32[shaderLength / 4];
	stream.Read(shader, shaderLength);

	auto shaderModuleCreateInfo = Framework::Vulkan::ShaderModuleCreateInfo();
	shaderModuleCreateInfo.codeSize = shaderLength;
	shaderModuleCreateInfo.pCode    = shader;

	auto result = m_device->vkCreateShaderModule(*m_device, &shaderModuleCreateInfo, nullptr, &m_handle);
	CHECKVULKANERROR(result);

	delete [] shader;
}

void CShaderModule::MoveFrom(CShaderModule&& rhs)
{
	std::swap(m_device, rhs.m_device);
	std::swap(m_handle, rhs.m_handle);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[]) {

	return 0;
}
<commit_msg>adding<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[]) {
	long n, m; scanf("%ld %ld\n", &n, &m);
	std::vector<std::vector<long> > edges(n + 1);
	std::vector<std::vector<bool> > adj(n + 1, std::vector<bool>(n + 1, 0));

	for(long p = 0; p < m; p++){long a, b; scanf("%ld %ld\n", &a, &b); edges[a].push_back(b); adj[a][b] = 1;}

	long long output(0);
	for(long source = 1; source <= n; source++){
		for(long target = 1; target <= n; target++){
			if(source == target){continue;}
			long long common = 0;
			for(long p = 0; p < edges[source].size(); p++){if(adj[edges[source][p]][target] > 0){++common;}}
			output += common * (common - 1) / 2;
		}
	}

	printf("%lld\n", output);

	return 0;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * 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.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: map.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef MAP_HPP
#define MAP_HPP

#ifdef HAVE_CONFIG_H
  #include <config.h>
#endif

#include <mapnik/feature_type_style.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <boost/optional/optional.hpp>

namespace mapnik
{
    class MAPNIK_DECL Map
    {
    public:

        enum aspect_fix_mode
        {
            /* grow the width or height of the specified geo bbox to fill the map size. default behaviour. */
            GROW_BBOX,
            /* grow the width or height of the map to accomodate the specified geo bbox. */
            GROW_CANVAS,
            /* shrink the width or height of the specified geo bbox to fill the map size. */
            SHRINK_BBOX,
            /* shrink the width or height of the map to accomodate the specified geo bbox. */
            SHRINK_CANVAS,
            /* adjust the width of the specified geo bbox, leave height and map size unchanged */
            ADJUST_BBOX_WIDTH,
            /* adjust the height of the specified geo bbox, leave width and map size unchanged */
            ADJUST_BBOX_HEIGHT,
            /* adjust the width of the map, leave height and geo bbox unchanged */
            ADJUST_CANVAS_WIDTH,
            /* adjust the height of the map, leave width and geo bbox unchanged */
            ADJUST_CANVAS_HEIGHT
        };
    private:
        static const unsigned MIN_MAPSIZE=16;
        static const unsigned MAX_MAPSIZE=MIN_MAPSIZE<<10;
        unsigned width_;
        unsigned height_;
        std::string  srs_;
        boost::optional<Color> background_;
        std::map<std::string,feature_type_style> styles_;
        std::map<std::string,FontSet> fontsets_;
        std::vector<Layer> layers_;
        Envelope<double> currentExtent_;
        aspect_fix_mode aspectFixMode_;

    public:

        typedef std::map<std::string,feature_type_style>::const_iterator const_style_iterator;
        typedef std::map<std::string,feature_type_style>::iterator style_iterator;

        /*! \brief Default constructor.
         *
         *  Creates a map with these parameters:
         *  - width = 400
         *  - height = 400
         *  - projection = "+proj=latlong +datum=WGS84"
         */
        Map();

        /*! \brief Constructor
         *  @param width Initial map width.
         *  @param height Initial map height.
         *  @param srs Initial map projection.
         */
        Map(int width, int height, std::string const& srs="+proj=latlong +datum=WGS84");

        /*! \brief Copy Constructur.
         *
         *  @param rhs Map to copy from.
         */
        Map(const Map& rhs);

        /*! \brief Assignment operator
         *
         *  TODO: to be documented
         *
         */
        Map& operator=(const Map& rhs);

        /*! \brief Get all styles
         * @return Const reference to styles
         */
        std::map<std::string,feature_type_style> const& styles() const;

        /*! \brief Get all styles
         * @return Non-constant reference to styles
         */
        std::map<std::string,feature_type_style> & styles();

        /*! \brief Get first iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator begin_styles() const;

        /*! \brief Get last iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator end_styles() const;

        /*! \brief Get first iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator begin_styles();

        /*! \brief Get last iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator end_styles();

        /*! \brief Insert a style in the map.
         *  @param name The name of the style.
         *  @param style The style to insert.
         *  @return true If success.
         *  @return false If no success.
         */
        bool insert_style(std::string const& name,feature_type_style const& style);

        /*! \brief Remove a style from the map.
         *  @param name The name of the style.
         */
        void remove_style(const std::string& name);

        /*! \brief Find a style.
         *  @param name The name of the style.
         *  @return The style if found. If not found return the default map style.
         */
        feature_type_style const& find_style(std::string const& name) const;

        /*! \brief Insert a fontset into the map.
         *  @param name The name of the fontset.
         *  @param style The fontset to insert.
         *  @return true If success.
         *  @return false If failure.
         */
        bool insert_fontset(std::string const& name, FontSet const& fontset);

        /*! \brief Find a fontset.
         *  @param name The name of the fontset.
         *  @return The fontset if found. If not found return the default map fontset.
         */
        FontSet const& find_fontset(std::string const& name) const;

        /*! \brief Get number of all layers.
         */
        size_t layerCount() const;

        /*! \brief Add a layer to the map.
         *  @param l The layer to add.
         */
        void addLayer(const Layer& l);

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Constant layer.
         */
        const Layer& getLayer(size_t index) const;

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Non-constant layer.
         */
        Layer& getLayer(size_t index);

        /*! \brief Remove a layer.
         *  @param index Layer number.
         */
        void removeLayer(size_t index);

        /*! \brief Get all layers.
         *  @return Constant layers.
         */
        std::vector<Layer> const& layers() const;

        /*! \brief Get all layers.
         *  @return Non-constant layers.
         */
        std::vector<Layer> & layers();

        /*! \brief Remove all layers and styles from the map.
         */
        void remove_all();

        /*! \brief Get map width.
         */
        unsigned getWidth() const;

        /*! \brief Get map height.
         */
        unsigned getHeight() const;

        /*! \brief Set map width.
         */
        void setWidth(unsigned width);

        /*! \brief Set map height.
         */
        void setHeight(unsigned height);

        /*! \brief Resize the map.
         */
        void resize(unsigned width,unsigned height);

        /*! \brief Get the map projection.
         *  @return Map projection.
         */
        std::string const& srs() const;

        /*! \brief Set the map projection.
         *  @param srs Map projection.
         */
        void set_srs(std::string const& srs);

        /*! \brief Set the map background color.
         *  @param c Background color.
         */
        void set_background(const Color& c);

        /*! \brief Get the map background color
         *  @return Background color as boost::optional
         *  object
         */
        boost::optional<Color> const& background() const;

        /*! \brief Zoom the map at the current position.
         *  @param factor The factor how much the map is zoomed in or out.
         */
        void zoom(double factor);

        /*! \brief Zoom the map to a bounding box.
         *
         *  Aspect is handled automatic if not fitting to width/height.
         *  @param box The bounding box where to zoom.
         */
        void zoomToBox(const Envelope<double>& box);

        /*! \brief Zoom the map to show all data.
         */
        void zoom_all();

        void pan(int x,int y);

        void pan_and_zoom(int x,int y,double zoom);

        /*! \brief Get current bounding box.
         *  @return The current bounding box.
         */
        const Envelope<double>& getCurrentExtent() const;

        double scale() const;

        CoordTransform view_transform() const;

        featureset_ptr query_point(unsigned index, double x, double y) const;

        featureset_ptr query_map_point(unsigned index, double x, double y) const;
        ~Map();

        void setAspectFixMode(aspect_fix_mode afm) { aspectFixMode_ = afm; }
        bool getAspectFixMode() { return aspectFixMode_; }

    private:
        void fixAspectRatio();
    };
}

#endif //MAP_HPP
<commit_msg>+fixed init order<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * 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.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id: map.hpp 39 2005-04-10 20:39:53Z pavlenko $

#ifndef MAP_HPP
#define MAP_HPP

#ifdef HAVE_CONFIG_H
  #include <config.h>
#endif

#include <mapnik/feature_type_style.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <boost/optional/optional.hpp>

namespace mapnik
{
    class MAPNIK_DECL Map
    {
    public:

        enum aspect_fix_mode
        {
            /* grow the width or height of the specified geo bbox to fill the map size. default behaviour. */
            GROW_BBOX,
            /* grow the width or height of the map to accomodate the specified geo bbox. */
            GROW_CANVAS,
            /* shrink the width or height of the specified geo bbox to fill the map size. */
            SHRINK_BBOX,
            /* shrink the width or height of the map to accomodate the specified geo bbox. */
            SHRINK_CANVAS,
            /* adjust the width of the specified geo bbox, leave height and map size unchanged */
            ADJUST_BBOX_WIDTH,
            /* adjust the height of the specified geo bbox, leave width and map size unchanged */
            ADJUST_BBOX_HEIGHT,
            /* adjust the width of the map, leave height and geo bbox unchanged */
            ADJUST_CANVAS_WIDTH,
            /* adjust the height of the map, leave width and geo bbox unchanged */
            ADJUST_CANVAS_HEIGHT
        };
    private:
        static const unsigned MIN_MAPSIZE=16;
        static const unsigned MAX_MAPSIZE=MIN_MAPSIZE<<10;
        unsigned width_;
        unsigned height_;
        std::string  srs_;
        boost::optional<Color> background_;
        std::map<std::string,feature_type_style> styles_;
        std::map<std::string,FontSet> fontsets_;
        std::vector<Layer> layers_;
        aspect_fix_mode aspectFixMode_;
        Envelope<double> currentExtent_;

    public:

        typedef std::map<std::string,feature_type_style>::const_iterator const_style_iterator;
        typedef std::map<std::string,feature_type_style>::iterator style_iterator;

        /*! \brief Default constructor.
         *
         *  Creates a map with these parameters:
         *  - width = 400
         *  - height = 400
         *  - projection = "+proj=latlong +datum=WGS84"
         */
        Map();

        /*! \brief Constructor
         *  @param width Initial map width.
         *  @param height Initial map height.
         *  @param srs Initial map projection.
         */
        Map(int width, int height, std::string const& srs="+proj=latlong +datum=WGS84");

        /*! \brief Copy Constructur.
         *
         *  @param rhs Map to copy from.
         */
        Map(const Map& rhs);

        /*! \brief Assignment operator
         *
         *  TODO: to be documented
         *
         */
        Map& operator=(const Map& rhs);

        /*! \brief Get all styles
         * @return Const reference to styles
         */
        std::map<std::string,feature_type_style> const& styles() const;

        /*! \brief Get all styles
         * @return Non-constant reference to styles
         */
        std::map<std::string,feature_type_style> & styles();

        /*! \brief Get first iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator begin_styles() const;

        /*! \brief Get last iterator in styles.
         *  @return Constant style iterator.
         */
        const_style_iterator end_styles() const;

        /*! \brief Get first iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator begin_styles();

        /*! \brief Get last iterator in styles.
         *  @return Non-constant style iterator.
         */
        style_iterator end_styles();

        /*! \brief Insert a style in the map.
         *  @param name The name of the style.
         *  @param style The style to insert.
         *  @return true If success.
         *  @return false If no success.
         */
        bool insert_style(std::string const& name,feature_type_style const& style);

        /*! \brief Remove a style from the map.
         *  @param name The name of the style.
         */
        void remove_style(const std::string& name);

        /*! \brief Find a style.
         *  @param name The name of the style.
         *  @return The style if found. If not found return the default map style.
         */
        feature_type_style const& find_style(std::string const& name) const;

        /*! \brief Insert a fontset into the map.
         *  @param name The name of the fontset.
         *  @param style The fontset to insert.
         *  @return true If success.
         *  @return false If failure.
         */
        bool insert_fontset(std::string const& name, FontSet const& fontset);

        /*! \brief Find a fontset.
         *  @param name The name of the fontset.
         *  @return The fontset if found. If not found return the default map fontset.
         */
        FontSet const& find_fontset(std::string const& name) const;

        /*! \brief Get number of all layers.
         */
        size_t layerCount() const;

        /*! \brief Add a layer to the map.
         *  @param l The layer to add.
         */
        void addLayer(const Layer& l);

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Constant layer.
         */
        const Layer& getLayer(size_t index) const;

        /*! \brief Get a layer.
         *  @param index Layer number.
         *  @return Non-constant layer.
         */
        Layer& getLayer(size_t index);

        /*! \brief Remove a layer.
         *  @param index Layer number.
         */
        void removeLayer(size_t index);

        /*! \brief Get all layers.
         *  @return Constant layers.
         */
        std::vector<Layer> const& layers() const;

        /*! \brief Get all layers.
         *  @return Non-constant layers.
         */
        std::vector<Layer> & layers();

        /*! \brief Remove all layers and styles from the map.
         */
        void remove_all();

        /*! \brief Get map width.
         */
        unsigned getWidth() const;

        /*! \brief Get map height.
         */
        unsigned getHeight() const;

        /*! \brief Set map width.
         */
        void setWidth(unsigned width);

        /*! \brief Set map height.
         */
        void setHeight(unsigned height);

        /*! \brief Resize the map.
         */
        void resize(unsigned width,unsigned height);

        /*! \brief Get the map projection.
         *  @return Map projection.
         */
        std::string const& srs() const;

        /*! \brief Set the map projection.
         *  @param srs Map projection.
         */
        void set_srs(std::string const& srs);

        /*! \brief Set the map background color.
         *  @param c Background color.
         */
        void set_background(const Color& c);

        /*! \brief Get the map background color
         *  @return Background color as boost::optional
         *  object
         */
        boost::optional<Color> const& background() const;

        /*! \brief Zoom the map at the current position.
         *  @param factor The factor how much the map is zoomed in or out.
         */
        void zoom(double factor);

        /*! \brief Zoom the map to a bounding box.
         *
         *  Aspect is handled automatic if not fitting to width/height.
         *  @param box The bounding box where to zoom.
         */
        void zoomToBox(const Envelope<double>& box);

        /*! \brief Zoom the map to show all data.
         */
        void zoom_all();

        void pan(int x,int y);

        void pan_and_zoom(int x,int y,double zoom);

        /*! \brief Get current bounding box.
         *  @return The current bounding box.
         */
        const Envelope<double>& getCurrentExtent() const;

        double scale() const;

        CoordTransform view_transform() const;

        featureset_ptr query_point(unsigned index, double x, double y) const;

        featureset_ptr query_map_point(unsigned index, double x, double y) const;
        ~Map();

        void setAspectFixMode(aspect_fix_mode afm) { aspectFixMode_ = afm; }
        bool getAspectFixMode() { return aspectFixMode_; }

    private:
        void fixAspectRatio();
    };
}

#endif //MAP_HPP
<|endoftext|>


<commit_before>#ifndef MPEL_TYPES_H
#define MPEL_TYPES_H

#include <opencv2/core/core.hpp>
#include <unordered_map>
#include <vector>

namespace mpel {
typedef cv::Point Point;
typedef const Point& PointRef;
}

namespace std {
template <> struct hash<mpel::Point> {
    size_t operator()(mpel::PointRef pt) const { return 10000 * pt.x + pt.y; }
};
}

namespace mpel {
struct Segment {
    Point p0, p1;
    Segment(PointRef a, PointRef b)
        : p0(a)
        , p1(b)
    {
    }
};
typedef const Segment& SegmentRef;

typedef std::vector<Point> Path;
typedef const Path& PathRef;

typedef cv::Mat Map;
typedef const Map& MapRef;

// A very very limited and inefficient implementation of graph
//
// each node contains a Point
// only add_edge operation is required
// -ve cost indicates not connected
class Graph {
public:
    typedef size_t vertex_t;

    Graph();
    ~Graph();
    vertex_t add_vertex(Point pt);
    void add_edge(Point pt1, Point pt2, double weight = 0);
    size_t descriptor(PointRef pt) const;
    size_t num_vertices() const;
    Point vertex(size_t n) const;
    double weight(PointRef a, PointRef b) const;
    double weight(size_t a, size_t b) const;
    const std::vector<Point>& vertex_list() const;
    bool connected() const;

private:
    std::vector<std::vector<double>> g;
    std::vector<Point> vertices;
    std::unordered_map<Point, vertex_t> vdesc;
    size_t nvertex;
    void allocate_vertex();
};
typedef const Graph& GraphRef;

struct Workspace {
    Map map;
};

struct ProblemDefinition {
    Point start;
    std::vector<Point> via; // via points (unimplemented)
    Point goal;
};
}

#endif
<commit_msg>Added doxygen info for types.hpp<commit_after>#ifndef MPEL_TYPES_H
#define MPEL_TYPES_H

#include <opencv2/core/core.hpp>
#include <unordered_map>
#include <vector>

namespace mpel {
/// The point datatype
typedef cv::Point Point;
typedef const Point& PointRef;
}

namespace std {
/// Hash for point type. Useful when using a map of points
template <> struct hash<mpel::Point> {
    size_t operator()(mpel::PointRef pt) const { return 10000 * pt.x + pt.y; }
};
}

namespace mpel {
/// The segment datatype
struct Segment {
    Point p0, p1;
    Segment(PointRef a, PointRef b)
        : p0(a)
        , p1(b)
    {
    }
};
typedef const Segment& SegmentRef;

/// The path datatype
typedef std::vector<Point> Path;
typedef const Path& PathRef;

/// The map datatype
typedef cv::Mat Map;
typedef const Map& MapRef;

// A very very limited and inefficient implementation of graph
//
// each node contains a Point
// only add_edge operation is required
// -ve cost indicates not connected
/**
 * \brief The graph datatype.
 *
 * This class implements a weighted, undirected graph. The graph
 * weights are always positive. negative weights represent the
 * absence of an edge between two vertices.
 */
class Graph {
public:
    typedef size_t vertex_t;

    /// The default constructor
    Graph();

    ~Graph();

    /// Adds vertex to the graph
    /// Vertices are unique and added only if it is not already present
    /// \return The vertex descriptor
    vertex_t add_vertex(Point pt);

    /// Adds an edge between two vertices
    /// Only one edge can be added between two vertices, the older edge
    /// is replaced if multiple edges are added. If the vertices are not
    /// already present in the graph, they are inerted as well.
    /// \param pt1 First vertex
    /// \param pt2 Second vertex
    /// \param weight The weight of this edge
    void add_edge(Point pt1, Point pt2, double weight = 0);

    /// Returns descriptor of the vertex
    size_t descriptor(PointRef pt) const;

    /// Returns number of vertices in the graph
    size_t num_vertices() const;

    /// Returns the vertex given its descriptor
    Point vertex(size_t n) const;

    /// Returns weight of the edge joining vertices a and b
    /// A negative value is returned if the vertices are not connected
    double weight(PointRef a, PointRef b) const;

    /// Returns weight of the edge joining two vertices given their descriptors
    /// A negative value is returned if the vertices are not connected
    double weight(size_t a, size_t b) const;

    /// Returns a vector of vertices in the graph
    const std::vector<Point>& vertex_list() const;

    /// Returns true if the graph is connected
    bool connected() const;

private:
    std::vector<std::vector<double>> g;
    std::vector<Point> vertices;
    std::unordered_map<Point, vertex_t> vdesc;
    size_t nvertex;
    void allocate_vertex();
};
typedef const Graph& GraphRef;

/// The workspace datatype
struct Workspace {
    Map map;
};

/// The problem definition datatype
struct ProblemDefinition {
    Point start;
    std::vector<Point> via; // via points (unimplemented)
    Point goal;
};
}

#endif
<|endoftext|>


<commit_before>// groundwater_aquitard.C --- Free drainage.
//
// Copyright 2008 Mikkel Mollerup, Per Abrahamsen and KU.
//
// This file is part of Daisy.
//
// Daisy is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// Daisy 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 Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with Daisy; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#define BUILD_DLL

#include "groundwater.h"
#include "block.h"
#include "librarian.h"
#include "check.h"
#include "assertion.h"
#include "depth.h"
#include "geometry.h"
#include "soil_water.h"
#include "log.h"
#include "treelog.h"
#include "frame.h"
#include <map>
#include <sstream>

#include <iostream>   //mmo

struct GroundwaterAquitard : public Groundwater
{
  // Parameters
  const double K_aquitard;  // Conductivity of the aquitard. [cm h^-1]
  const double Z_aquitard;    // Vertical length of the aquitard. [cm]
  std::auto_ptr<Depth> pressure_table; // Virtual groundwater height. [cm]
  double h_aquifer;          // Pressure potential in the aquifer [cm]

  // Utility.
  void set_h_aquifer (const Geometry& geo)
  {
    const double aquitard_bottom = geo.bottom () - Z_aquitard;
    h_aquifer = pressure_table->operator()() - aquitard_bottom;
  }

  // Bottom flux.
  typedef std::map<size_t, double> edge_flux_map;
  edge_flux_map edge_flux;
  bottom_t bottom_type() const
  { return forced_flux; }
  double q_bottom (size_t edge) const
  {
    edge_flux_map::const_iterator i = edge_flux.find (edge);
    daisy_assert (i != edge_flux.end ());
    return (*i).second;
  }

  // Simulation.
  void tick (const Units& units, const Geometry& geo,
             const Soil&, SoilWater& soil_water, double,
	     const SoilHeat&, const Time& time,
             const Scope& scope, Treelog& msg)
  {
    // Virtual pressure table.
    pressure_table->tick (units, time, scope, msg);
    set_h_aquifer (geo);

    // Deep percolation.
    const std::vector<size_t>& bottom_edges
      = geo.cell_edges (Geometry::cell_below);
    const size_t bottom_edges_size = bottom_edges.size ();

    for (size_t i = 0; i < bottom_edges_size; i++)
      {
        const size_t edge = bottom_edges[i];
        const int cell = geo.edge_other (edge, Geometry::cell_below);
        daisy_assert (geo.cell_is_internal (cell));
        const double in_sign = (geo.edge_to (edge) == cell) ? 1.0 : -1.0;

        // Multiplied with 2 because it is a boundary cell...
        const double Dz_i = 2 * geo.edge_length (edge);

        const double K_i = soil_water.K (cell);   //Conductivity in cell
        const double h_i = soil_water.h (cell);   //Pressure in cell

        const double numerator = K_i * (2.0 * h_i / Dz_i + 1.0)
          + K_aquitard * (h_aquifer / Z_aquitard - 1.0);
        const double denominator = K_aquitard + 2.0 * K_i * Z_aquitard / Dz_i;

        // Flux into domain.
        const double q_up = -K_aquitard * (numerator / denominator
                                           - h_aquifer / Z_aquitard + 1.0);
        edge_flux[edge] = in_sign * q_up;

#if 0
        Treelog::Open nest (msg, geo.edge_name (edge));
        std::ostringstream tmp;
        tmp << "cell = " << geo.cell_name (cell) << "\n"
            << "in_sign = " << in_sign << "\n"
            << "Dz_i = " <<  Dz_i << "\n"
            << "K_i = " << K_i << "\n"
            << "h_i = " << h_i << "\n"
            << "numerator = " << numerator << "\n"
            << "denominator = " << denominator << "\n"
            << "q_up = " << q_up << "\n"
            << "h_aquifer = " << h_aquifer << "\n"
            << "Z_aquitard = " << Z_aquitard << "\n"
            << "K_aquitard = " << K_aquitard;
        msg.message (tmp.str ());
#endif
      }
  }
  void output (Log& log) const
  {
    Groundwater::output (log);
    output_variable (h_aquifer, log);
  }

  double table () const
  { return pressure_table->operator()(); }

  // Create and Destroy.
  void initialize (const Units& units, const Geometry& geo, const Time&,
                   const Scope& scope, Treelog& msg)
  {
    if (!pressure_table.get ())
      pressure_table.reset (Depth::create ((geo.bottom () - Z_aquitard)
                                           + h_aquifer));
    pressure_table->initialize (units, scope, msg);
    // Pressure below aquitard.
    if (pressure_table->check (units, scope, msg))
      set_h_aquifer (geo);
    else
      pressure_table.reset (NULL);
  }
  bool check (const Units& units, const Geometry& geo, const Scope& scope,
              Treelog& msg) const
  {
    bool ok = true;
    if (!pressure_table.get ())
      {
        ok = false;
        msg.error ("No pressure table");
      }
    else if (!pressure_table->check (units, scope, msg))
      ok = false;
    return ok;
  }
  GroundwaterAquitard (Block& al)
    : Groundwater (al),
      K_aquitard (al.number ("K_aquitard")),
      Z_aquitard (al.number ("Z_aquitard")),
      pressure_table (al.check ("pressure_table")
                      ? Librarian::build_item<Depth> (al, "pressure_table")
                      : NULL),
      h_aquifer (al.number ("h_aquifer", Z_aquitard))
  {}
  ~GroundwaterAquitard ()
  { }
};

static struct GroundwaterAquitardSyntax : public DeclareModel
{
  Model* make (Block& al) const
  { return new GroundwaterAquitard (al); }

  GroundwaterAquitardSyntax ()
    : DeclareModel (Groundwater::component, "aquitard", "common", "\
Aquitard groundwater, free drainage.")
  { }
  void load_frame (Frame& frame) const
    {
      frame.declare ("K_aquitard", "cm/h", Check::non_negative (), Value::Const,
		  "Conductivity of the aquitard.");
      frame.set ("K_aquitard", 1e-3);
      frame.declare ("Z_aquitard", "cm", Check::positive (), Value::Const,
		  "Thickness of the aquitard.\n\
The aquitard begins below the bottommost soil horizon.");
      frame.set ("Z_aquitard", 200.0);
      frame.declare ("h_aquifer", "cm", Check::positive (), Value::OptionalState,
		  "Pressure potential in the aquifer below the aquitard.\n\
By default. this is Z_aquitard.\n\
You can alternatively specify the pressure as a virtual groundwater level.\n\
See 'pressure_table'.");
      frame.declare_object ("pressure_table", Depth::component,
                         Value::OptionalConst, Value::Singleton, "\
Height of groundwater the corresponds to the pressure in the aquifer.  \n\
\n\
If you drilled a well down to the aquifer, this is number what the\n\
water level in the well would be as height above ground (a negative\n\
number).  This is different from the actual groundwater table, because\n\
the aquitart block the water, and the pipes lead the water away.\n\
You can alternatively specify the pressure directly, with 'h_aquifer'.");
    }
} GroundwaterAquitard_syntax;

// groundwater_aquitard.C ends here.
<commit_msg>x61s<commit_after>// groundwater_aquitard.C --- Free drainage.
//
// Copyright 2008 Mikkel Mollerup, Per Abrahamsen and KU.
//
// This file is part of Daisy.
//
// Daisy is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// Daisy 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 Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with Daisy; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#define BUILD_DLL

#include "groundwater.h"
#include "block.h"
#include "librarian.h"
#include "check.h"
#include "assertion.h"
#include "depth.h"
#include "geometry.h"
#include "soil_water.h"
#include "log.h"
#include "treelog.h"
#include "frame.h"
#include <map>
#include <sstream>

#include <iostream>   //mmo

struct GroundwaterAquitard : public Groundwater
{
  // Parameters
  const double K_aquitard;  // Conductivity of the aquitard. [cm h^-1]
  const double Z_aquitard;    // Vertical length of the aquitard. [cm]
  std::auto_ptr<Depth> pressure_table; // Virtual groundwater height. [cm]
  double h_aquifer;          // Pressure potential in the aquifer [cm]

  // Utility.
  void set_h_aquifer (const Geometry& geo)
  {
    const double aquitard_bottom = geo.bottom () - Z_aquitard;
    h_aquifer = pressure_table->operator()() - aquitard_bottom;
  }

  // Bottom flux.
  typedef std::map<size_t, double> edge_flux_map;
  edge_flux_map edge_flux;
  bottom_t bottom_type() const
  { return forced_flux; }
  double q_bottom (size_t edge) const
  {
    edge_flux_map::const_iterator i = edge_flux.find (edge);
    daisy_assert (i != edge_flux.end ());
    return (*i).second;
  }

  // Simulation.
  void tick (const Units& units, const Geometry& geo,
             const Soil&, SoilWater& soil_water, double,
	     const SoilHeat&, const Time& time,
             const Scope& scope, Treelog& msg)
  {
    // Virtual pressure table.
    pressure_table->tick (units, time, scope, msg);
    set_h_aquifer (geo);

    // Deep percolation.
    const std::vector<size_t>& bottom_edges
      = geo.cell_edges (Geometry::cell_below);
    const size_t bottom_edges_size = bottom_edges.size ();

    for (size_t i = 0; i < bottom_edges_size; i++)
      {
        const size_t edge = bottom_edges[i];
        const int cell = geo.edge_other (edge, Geometry::cell_below);
        daisy_assert (geo.cell_is_internal (cell));
        const double in_sign = (geo.edge_to (edge) == cell) ? 1.0 : -1.0;

        // Multiplied with 2 because it is a boundary cell...
        const double Dz_i = 2 * geo.edge_length (edge);

        const double K_i = soil_water.K (cell);   //Conductivity in cell
        const double h_i = soil_water.h (cell);   //Pressure in cell

        const double numerator = K_i * (2.0 * h_i / Dz_i + 1.0)
          + K_aquitard * (h_aquifer / Z_aquitard - 1.0);
        const double denominator = K_aquitard + 2.0 * K_i * Z_aquitard / Dz_i;

        // Flux into domain.
        const double q_up = -K_aquitard * (numerator / denominator
                                           - h_aquifer / Z_aquitard + 1.0);
        edge_flux[edge] = in_sign * q_up;

#if 0
        Treelog::Open nest (msg, geo.edge_name (edge));
        std::ostringstream tmp;
        tmp << "cell = " << geo.cell_name (cell) << "\n"
            << "in_sign = " << in_sign << "\n"
            << "Dz_i = " <<  Dz_i << "\n"
            << "K_i = " << K_i << "\n"
            << "h_i = " << h_i << "\n"
            << "numerator = " << numerator << "\n"
            << "denominator = " << denominator << "\n"
            << "q_up = " << q_up << "\n"
            << "h_aquifer = " << h_aquifer << "\n"
            << "Z_aquitard = " << Z_aquitard << "\n"
            << "K_aquitard = " << K_aquitard;
        msg.message (tmp.str ());
#endif
      }
  }
  void output (Log& log) const
  {
    Groundwater::output (log);
    output_variable (h_aquifer, log);
  }

  double table () const
  { return pressure_table->operator()(); }

  // Create and Destroy.
  void initialize (const Units& units, const Geometry& geo, const Time& time,
                   const Scope& scope, Treelog& msg)
  {
    if (!pressure_table.get ())
      pressure_table.reset (Depth::create ((geo.bottom () - Z_aquitard)
                                           + h_aquifer));
    pressure_table->initialize (units, scope, msg);
    Time prev = time;
    prev.tick_hour (-1);
    pressure_table->tick (units, prev, scope, msg);
    pressure_table->tick (units, time, scope, msg);
    // Pressure below aquitard.
    if (pressure_table->check (units, scope, msg))
      set_h_aquifer (geo);
    else
      pressure_table.reset (NULL);
  }
  bool check (const Units& units, const Geometry& geo, const Scope& scope,
              Treelog& msg) const
  {
    bool ok = true;
    if (!pressure_table.get ())
      {
        ok = false;
        msg.error ("No pressure table");
      }
    else if (!pressure_table->check (units, scope, msg))
      ok = false;
    return ok;
  }
  GroundwaterAquitard (Block& al)
    : Groundwater (al),
      K_aquitard (al.number ("K_aquitard")),
      Z_aquitard (al.number ("Z_aquitard")),
      pressure_table (al.check ("pressure_table")
                      ? Librarian::build_item<Depth> (al, "pressure_table")
                      : NULL),
      h_aquifer (al.number ("h_aquifer", Z_aquitard))
  {}
  ~GroundwaterAquitard ()
  { }
};

static struct GroundwaterAquitardSyntax : public DeclareModel
{
  Model* make (Block& al) const
  { return new GroundwaterAquitard (al); }

  GroundwaterAquitardSyntax ()
    : DeclareModel (Groundwater::component, "aquitard", "common", "\
Aquitard groundwater, free drainage.")
  { }
  void load_frame (Frame& frame) const
    {
      frame.declare ("K_aquitard", "cm/h", Check::non_negative (), Value::Const,
		  "Conductivity of the aquitard.");
      frame.set ("K_aquitard", 1e-3);
      frame.declare ("Z_aquitard", "cm", Check::positive (), Value::Const,
		  "Thickness of the aquitard.\n\
The aquitard begins below the bottommost soil horizon.");
      frame.set ("Z_aquitard", 200.0);
      frame.declare ("h_aquifer", "cm", Check::positive (), Value::OptionalState,
		  "Pressure potential in the aquifer below the aquitard.\n\
By default. this is Z_aquitard.\n\
You can alternatively specify the pressure as a virtual groundwater level.\n\
See 'pressure_table'.");
      frame.declare_object ("pressure_table", Depth::component,
                         Value::OptionalConst, Value::Singleton, "\
Height of groundwater the corresponds to the pressure in the aquifer.  \n\
\n\
If you drilled a well down to the aquifer, this is number what the\n\
water level in the well would be as height above ground (a negative\n\
number).  This is different from the actual groundwater table, because\n\
the aquitart block the water, and the pipes lead the water away.\n\
You can alternatively specify the pressure directly, with 'h_aquifer'.");
    }
} GroundwaterAquitard_syntax;

// groundwater_aquitard.C ends here.
<|endoftext|>


<commit_before>/*
Copyright (C) 2016 - Gbor "Razzie" Grzsny

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
*/

#pragma once

#include <cstdint>
#include <cstring> // memset & memcpy
#include <iterator>
#include <stdexcept>

namespace raz
{
	template<size_t N>
	class Bitset
	{
	public:
		class TrueBitIterator : public std::iterator<std::input_iterator_tag, size_t, size_t, const size_t*, size_t>
		{
		public:
			TrueBitIterator(const TrueBitIterator& other) :
				m_data(other.m_data), m_bit(other.m_bit), m_last_bit(other.m_last_bit)
			{
			}

			TrueBitIterator& operator=(const TrueBitIterator& other)
			{
				m_data = other.m_data;
				m_bit = other.m_bit;
				m_last_bit = other.m_last_bit;
				return *this;
			}

			TrueBitIterator& operator++()
			{
				if (m_bit < m_last_bit)
				{
					++m_bit;
					findNext();
				}
				return *this;
			}

			TrueBitIterator operator++(int)
			{
				TrueBitIterator retval = *this;
				++(*this);
				return retval;
			}

			bool operator==(const TrueBitIterator& other) const
			{
				return (m_bit == other.m_bit && m_data == other.m_data && m_last_bit == other.m_last_bit);
			}

			bool operator!=(const TrueBitIterator& other) const
			{
				return !(*this == other);
			}

			reference operator*() const
			{
				return static_cast<reference>(m_bit);
			}

		private:
			const uint32_t* m_data;
			size_t m_bit;
			size_t m_last_bit;

			friend class Bitset;

			TrueBitIterator(const uint32_t* data, size_t bit, size_t last_bit) :
				m_data(data), m_bit(bit), m_last_bit(last_bit)
			{
				findNext();
			}

			void findNext()
			{
				while (true)
				{
					if (m_bit >= m_last_bit)
					{
						m_bit = m_last_bit;
						return;
					}

					uint32_t value = m_data[m_bit / 32] >> (m_bit % 32);

					if (value == 0)
					{
						m_bit += (32 - (m_bit % 32));
						continue;
					}

					if ((value & 1) != 0)
						break;

					++m_bit;
				}
			}
		};

		class FalseBitIterator : public std::iterator<std::input_iterator_tag, size_t, size_t, const size_t*, size_t>
		{
		public:
			FalseBitIterator(const FalseBitIterator& other) :
				m_data(other.m_data), m_bit(other.m_bit), m_last_bit(other.m_last_bit)
			{
			}

			FalseBitIterator& operator=(const FalseBitIterator& other)
			{
				m_data = other.m_data;
				m_bit = other.m_bit;
				m_last_bit = other.m_last_bit;
				return *this;
			}

			FalseBitIterator& operator++()
			{
				if (m_bit < m_last_bit)
				{
					++m_bit;
					findNext();
				}
				return *this;
			}

			FalseBitIterator operator++(int)
			{
				FalseBitIterator retval = *this;
				++(*this);
				return retval;
			}

			bool operator==(const FalseBitIterator& other) const
			{
				return (m_bit == other.m_bit && m_data == other.m_data && m_last_bit == other.m_last_bit);
			}

			bool operator!=(const FalseBitIterator& other) const
			{
				return !(*this == other);
			}

			reference operator*() const
			{
				return static_cast<reference>(m_bit);
			}

		private:
			const uint32_t* m_data;
			size_t m_bit;
			size_t m_last_bit;

			friend class Bitset;

			FalseBitIterator(const uint32_t* data, size_t bit, size_t last_bit) :
				m_data(data), m_bit(bit), m_last_bit(last_bit)
			{
				findNext();
			}

			void findNext()
			{
				while (true)
				{
					if (m_bit >= m_last_bit)
					{
						m_bit = m_last_bit;
						return;
					}

					uint32_t value = ~m_data[m_bit / 32] >> (m_bit % 32);

					if (value == 0)
					{
						m_bit += (32 - (m_bit % 32));
						continue;
					}

					if ((value & 1) != 0)
						break;

					++m_bit;
				}
			}
		};

		class TrueBits
		{
		public:
			TrueBits(const TrueBits& other) : m_bitset(other.m_bitset)
			{
			}

			size_t count() const
			{
				size_t count = 0;

				for (size_t i = 0; i < DATA_SIZE; ++i)
					count += countTrueBits(m_bitset->m_data[i]);

				return count;
			}

			TrueBitIterator begin() const
			{
				return TrueBitIterator(m_bitset->m_data, 0, N);
			}

			TrueBitIterator end() const
			{
				return TrueBitIterator(m_bitset->m_data, N, N);
			}

		private:
			friend class Bitset;

			TrueBits(const Bitset* bitset) : m_bitset(bitset)
			{
			}

			const Bitset* m_bitset;
		};

		class FalseBits
		{
		public:
			FalseBits(const FalseBits& other) : m_bitset(other.m_bitset)
			{
			}

			size_t count() const
			{
				size_t count = 0;

				for (size_t i = 0; i < DATA_SIZE; ++i)
					count += countFalseBits(m_bitset->m_data[i]);

				return N - count;
			}

			FalseBitIterator begin() const
			{
				return FalseBitIterator(m_bitset->m_data, 0, N);
			}

			FalseBitIterator end() const
			{
				return FalseBitIterator(m_bitset->m_data, N, N);
			}

		private:
			friend class Bitset;

			FalseBits(const Bitset* bitset) : m_bitset(bitset)
			{
			}

			const Bitset* m_bitset;
		};

		Bitset()
		{
			reset();
		}

		Bitset(const Bitset& other)
		{
			std::memcpy(m_data, other.m_data, sizeof(m_data));
		}

		bool isset(size_t pos) const
		{
			if (pos >= N)
				throw std::out_of_range({});

			return (m_data[pos / 32] & (1u << (pos % 32))) != 0;
		}

		void set(size_t pos)
		{
			if (pos >= N)
				throw std::out_of_range({});

			m_data[pos / 32] |= (1u << (pos % 32));
		}

		void unset(size_t pos)
		{
			if (pos >= N)
				throw std::out_of_range({});

			m_data[pos / 32] &= ~(1u << (pos % 32));
		}

		void reset()
		{
			std::memset(m_data, 0, sizeof(m_data));
		}

		const void* data() const
		{
			return m_data;
		}

		size_t size() const
		{
			return sizeof(m_data);
		}

		TrueBits truebits() const
		{
			return TrueBits(this);
		}

		FalseBits falsebits() const
		{
			return FalseBits(this);
		}

		template<class Serializer>
		void operator()(Serializer& serializer)
		{
			for (size_t i = 0; i < DATA_SIZE; ++i)
				serializer(m_data[i]);
		}

	private:
		static constexpr size_t DATA_SIZE = ((N - 1) / 32) + 1;
		uint32_t m_data[DATA_SIZE];

		static size_t countTrueBits(uint32_t x)
		{
			x = x - ((x >> 1) & 0x55555555);
			x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
			x = (x + (x >> 4)) & 0x0F0F0F0F;
			x = x + (x >> 8);
			x = x + (x >> 16);
			return x & 0x0000003F;
		}
	};
}
<commit_msg>Improved Bitset true and false bit iteration algorithm<commit_after>/*
Copyright (C) 2016 - Gbor "Razzie" Grzsny

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
*/

#pragma once

#include <cstdint>
#include <cstring> // memset & memcpy
#include <iterator>
#include <stdexcept>

namespace raz
{
	template<size_t N>
	class Bitset
	{
	public:
		class TrueBitIterator : public std::iterator<std::input_iterator_tag, size_t, size_t, const size_t*, size_t>
		{
		public:
			TrueBitIterator(const TrueBitIterator& other) :
				m_data(other.m_data), m_bit(other.m_bit), m_last_bit(other.m_last_bit)
			{
			}

			TrueBitIterator& operator=(const TrueBitIterator& other)
			{
				m_data = other.m_data;
				m_bit = other.m_bit;
				m_last_bit = other.m_last_bit;
				return *this;
			}

			TrueBitIterator& operator++()
			{
				if (m_bit < m_last_bit)
				{
					++m_bit;
					findNext();
				}
				return *this;
			}

			TrueBitIterator operator++(int)
			{
				TrueBitIterator retval = *this;
				++(*this);
				return retval;
			}

			bool operator==(const TrueBitIterator& other) const
			{
				return (m_bit == other.m_bit && m_data == other.m_data && m_last_bit == other.m_last_bit);
			}

			bool operator!=(const TrueBitIterator& other) const
			{
				return !(*this == other);
			}

			reference operator*() const
			{
				return static_cast<reference>(m_bit);
			}

		private:
			const uint32_t* m_data;
			size_t m_bit;
			size_t m_last_bit;

			friend class Bitset;

			TrueBitIterator(const uint32_t* data, size_t bit, size_t last_bit) :
				m_data(data), m_bit(bit), m_last_bit(last_bit)
			{
				findNext();
			}

			void findNext()
			{
				if (m_bit == m_last_bit)
					return;

				uint32_t value;

				if (m_bit % 32)
					value = m_data[m_bit / 32] >> ((m_bit % 32) - 1);

				do
				{
					if (m_bit % 32)
						value >>= 1;
					else
						value = m_data[m_bit / 32] >> (m_bit % 32);

					if (value == 0)
						m_bit += (32 - (m_bit % 32)); // skip the remaining of this 32bit block
					else if ((value & 1) != 0)
						return;
					else
						++m_bit;

				} while (m_bit < m_last_bit);

				if (m_bit >= m_last_bit)
					m_bit = m_last_bit;
			}
		};

		class FalseBitIterator : public std::iterator<std::input_iterator_tag, size_t, size_t, const size_t*, size_t>
		{
		public:
			FalseBitIterator(const FalseBitIterator& other) :
				m_data(other.m_data), m_bit(other.m_bit), m_last_bit(other.m_last_bit)
			{
			}

			FalseBitIterator& operator=(const FalseBitIterator& other)
			{
				m_data = other.m_data;
				m_bit = other.m_bit;
				m_last_bit = other.m_last_bit;
				return *this;
			}

			FalseBitIterator& operator++()
			{
				if (m_bit < m_last_bit)
				{
					++m_bit;
					findNext();
				}
				return *this;
			}

			FalseBitIterator operator++(int)
			{
				FalseBitIterator retval = *this;
				++(*this);
				return retval;
			}

			bool operator==(const FalseBitIterator& other) const
			{
				return (m_bit == other.m_bit && m_data == other.m_data && m_last_bit == other.m_last_bit);
			}

			bool operator!=(const FalseBitIterator& other) const
			{
				return !(*this == other);
			}

			reference operator*() const
			{
				return static_cast<reference>(m_bit);
			}

		private:
			const uint32_t* m_data;
			size_t m_bit;
			size_t m_last_bit;

			friend class Bitset;

			FalseBitIterator(const uint32_t* data, size_t bit, size_t last_bit) :
				m_data(data), m_bit(bit), m_last_bit(last_bit)
			{
				findNext();
			}

			void findNext()
			{
				if (m_bit == m_last_bit)
					return;

				uint32_t value;

				if (m_bit % 32)
					value = ~m_data[m_bit / 32] >> ((m_bit % 32) - 1);

				do
				{
					if (m_bit % 32)
						value >>= 1;
					else
						value = ~m_data[m_bit / 32] >> (m_bit % 32);

					if (value == 0)
						m_bit += (32 - (m_bit % 32)); // skip the remaining of this 32bit block
					else if ((value & 1) != 0)
						return;
					else
						++m_bit;

				} while (m_bit < m_last_bit);

				if (m_bit >= m_last_bit)
					m_bit = m_last_bit;
			}
		};

		class TrueBits
		{
		public:
			TrueBits(const TrueBits& other) : m_bitset(other.m_bitset)
			{
			}

			size_t count() const
			{
				size_t count = 0;

				for (size_t i = 0; i < DATA_SIZE; ++i)
					count += countTrueBits(m_bitset->m_data[i]);

				return count;
			}

			TrueBitIterator begin() const
			{
				return TrueBitIterator(m_bitset->m_data, 0, N);
			}

			TrueBitIterator end() const
			{
				return TrueBitIterator(m_bitset->m_data, N, N);
			}

		private:
			friend class Bitset;

			TrueBits(const Bitset* bitset) : m_bitset(bitset)
			{
			}

			const Bitset* m_bitset;
		};

		class FalseBits
		{
		public:
			FalseBits(const FalseBits& other) : m_bitset(other.m_bitset)
			{
			}

			size_t count() const
			{
				size_t count = 0;

				for (size_t i = 0; i < DATA_SIZE; ++i)
					count += countFalseBits(m_bitset->m_data[i]);

				return N - count;
			}

			FalseBitIterator begin() const
			{
				return FalseBitIterator(m_bitset->m_data, 0, N);
			}

			FalseBitIterator end() const
			{
				return FalseBitIterator(m_bitset->m_data, N, N);
			}

		private:
			friend class Bitset;

			FalseBits(const Bitset* bitset) : m_bitset(bitset)
			{
			}

			const Bitset* m_bitset;
		};

		Bitset()
		{
			reset();
		}

		Bitset(const Bitset& other)
		{
			std::memcpy(m_data, other.m_data, sizeof(m_data));
		}

		bool isset(size_t pos) const
		{
			if (pos >= N)
				throw std::out_of_range({});

			return (m_data[pos / 32] & (1u << (pos % 32))) != 0;
		}

		void set(size_t pos)
		{
			if (pos >= N)
				throw std::out_of_range({});

			m_data[pos / 32] |= (1u << (pos % 32));
		}

		void unset(size_t pos)
		{
			if (pos >= N)
				throw std::out_of_range({});

			m_data[pos / 32] &= ~(1u << (pos % 32));
		}

		void reset()
		{
			std::memset(m_data, 0, sizeof(m_data));
		}

		const void* data() const
		{
			return m_data;
		}

		size_t size() const
		{
			return sizeof(m_data);
		}

		TrueBits truebits() const
		{
			return TrueBits(this);
		}

		FalseBits falsebits() const
		{
			return FalseBits(this);
		}

		template<class Serializer>
		void operator()(Serializer& serializer)
		{
			for (size_t i = 0; i < DATA_SIZE; ++i)
				serializer(m_data[i]);
		}

	private:
		static constexpr size_t DATA_SIZE = ((N - 1) / 32) + 1;
		uint32_t m_data[DATA_SIZE];

		static size_t countTrueBits(uint32_t x)
		{
			x = x - ((x >> 1) & 0x55555555);
			x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
			x = (x + (x >> 4)) & 0x0F0F0F0F;
			x = x + (x >> 8);
			x = x + (x >> 16);
			return x & 0x0000003F;
		}
	};
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <chrono>
#include <memory>
#include <cmath>
#include <signal.h>

#include <SmurffCpp/Types.h>

#include <SmurffCpp/DataMatrices/Data.h>
#include <SmurffCpp/Utils/Distribution.h>

#include <SmurffCpp/Model.h>

#include <SmurffCpp/VMatrixIterator.hpp>
#include <SmurffCpp/ConstVMatrixIterator.hpp>
#include <SmurffCpp/VMatrixExprIterator.hpp>
#include <SmurffCpp/ConstVMatrixExprIterator.hpp>

#include <Utils/Error.h>
#include <SmurffCpp/Utils/SaveState.h>

namespace smurff {

Model::Model()
   : m_num_latent(-1), m_dims(0)
{
}

//num_latent - size of latent dimension
//dims - dimentions of train data
//init_model_type - samples initialization type
void Model::init(int num_latent, const PVec<>& dims, ModelInitTypes model_init_type, bool save_model, bool aggregate)
{
   size_t nmodes = dims.size();

   m_num_latent = num_latent;
   m_dims = dims;
   m_collect_aggr = aggregate;
   m_save_model = save_model;
   m_num_aggr = std::vector<int>(dims.size(), 0);

   m_factors.resize(nmodes);
   m_link_matrices.resize(nmodes);
   m_mus.resize(nmodes);

   for(size_t i = 0; i < nmodes; ++i)
   {
      Matrix& mat = m_factors.at(i);
      mat.resize(dims[i], m_num_latent);

      switch(model_init_type)
      {
      case ModelInitTypes::random:
         mat = Matrix::NullaryExpr(mat.rows(), mat.cols(), RandNormalGenerator());
         break;
      case ModelInitTypes::zero:
         mat.setZero();
         break;
      default:
         {
            THROWERROR("Invalid model init type");
         }
      }

      if (aggregate)
      {
         m_aggr_sum.push_back(Matrix::Zero(dims[i], m_num_latent));
         m_aggr_dot.push_back(Matrix::Zero(dims[i], m_num_latent * m_num_latent));
      }
   }

   Pcache.init(Array1D::Ones(m_num_latent));
}

Matrix &Model::getLinkMatrix(int mode)
{
   return m_link_matrices.at(mode);
}

Vector &Model::getMu(int mode)
{
   return m_mus.at(mode);
}

const Matrix &Model::getLinkMatrix(int mode) const
{
   return m_link_matrices.at(mode);
}

const Vector &Model::getMu(int mode) const
{
   return m_mus.at(mode);
}

double Model::predict(const PVec<> &pos) const
{
   if (nmodes() == 2)
   {
      return row(0, pos[0]).dot(row(1, pos[1]));
   }

   auto &P = Pcache.local();
   P.setOnes();
   for(uint32_t d = 0; d < nmodes(); ++d)
      P *= row(d, pos.at(d)).array();
   return P.sum();
}

const Matrix &Model::U(uint32_t f) const
{
   return m_factors.at(f);
}

Matrix &Model::U(uint32_t f)
{
   return m_factors[f];
}

VMatrixIterator<Matrix> Model::Vbegin(std::uint32_t mode)
{
   return VMatrixIterator<Matrix>(this, mode, 0);
}

VMatrixIterator<Matrix> Model::Vend()
{
   return VMatrixIterator<Matrix>(m_factors.size());
}

ConstVMatrixIterator<Matrix> Model::CVbegin(std::uint32_t mode) const
{
   return ConstVMatrixIterator<Matrix>(this, mode, 0);
}

ConstVMatrixIterator<Matrix> Model::CVend() const
{
   return ConstVMatrixIterator<Matrix>(m_factors.size());
}

Matrix::ConstRowXpr Model::row(int f, int i) const
{
   return U(f).row(i);
}

std::uint64_t Model::nmodes() const
{
   return m_factors.size();
}

int Model::nlatent() const
{
   return m_num_latent;
}

int Model::nsamples() const
{
   return std::accumulate(m_factors.begin(), m_factors.end(), 0,
      [](const int &a, const Matrix &b) { return a + b.rows(); });
}

const PVec<>& Model::getDims() const
{
   return m_dims;
}

SubModel Model::full()
{
   return SubModel(*this);
}

void Model::updateAggr(int m, int i)
{
   if (!m_collect_aggr) return;

   const auto &r = row(m, i);
   Matrix cov = (r.transpose() * r);
   m_aggr_sum.at(m).row(i) += r;
   m_aggr_dot.at(m).row(i) += Eigen::Map<Vector>(cov.data(), nlatent() * nlatent());
}

void Model::updateAggr(int m)
{
   m_num_aggr.at(m)++;
}

void Model::save(SaveState &sf) const
{
   sf.putModel(m_factors);
   for (std::uint64_t m = 0; m < nmodes(); ++m)
   {
      sf.putLinkMatrix(m, m_link_matrices.at(m));
      sf.putMu(m, m_mus.at(m));

      if (m_collect_aggr && m_save_aggr)
      {
         double n = m_num_aggr.at(m);

         const Matrix &Usum = m_aggr_sum.at(m);
         const Matrix &Uprod = m_aggr_dot.at(m);

         Matrix mu = Matrix::Zero(Usum.rows(), Usum.cols());
         // inverse of the covariance
         Matrix prec = Matrix::Zero(Uprod.rows(), Uprod.cols());

         // calculate real mu and Lambda
         for (int i = 0; i < U(m).rows(); i++)
         {
            Vector sum = Usum.row(i);
            Matrix prod = Eigen::Map<const Matrix>(Uprod.row(i).data(), nlatent(), nlatent());
            Matrix prec_i = ((prod - (sum.transpose() * sum / n)) / (n - 1)).inverse();

            prec.row(i) = Eigen::Map<Vector>(prec_i.data(), nlatent() * nlatent());
            mu.row(i) = sum / n;
         }

         sf.putPostMuLambda(m, mu, prec);
      }
   }
}

void Model::restore(const SaveState &sf, int skip_mode)
{
   unsigned nmodes = sf.getNModes();
   m_factors.clear();
   m_dims = PVec<>(nmodes);
   m_factors.resize(nmodes);

   for (std::uint64_t i = 0; i < nmodes; ++i)
   {
      if ((int)i != skip_mode)
      {
         auto &U = m_factors.at(i);
         sf.readModel(i, U);
         m_dims.at(i) = U.rows();
         m_num_latent = U.cols();
      }
      else
      {
         m_dims.at(i) = -1;
      }
   }

   m_link_matrices.resize(nmodes);
   m_mus.resize(nmodes);

   for(unsigned i=0; i<nmodes; ++i)
   {
      sf.readLinkMatrix(i, m_link_matrices.at(i));
      sf.readMu(i, m_mus.at(i));
   }

   Pcache.init(Array1D::Ones(m_num_latent));
}

std::ostream& Model::info(std::ostream &os, std::string indent) const
{
   os << indent << "Num-latents: " << m_num_latent << std::endl;
   return os;
}

std::ostream& Model::status(std::ostream &os, std::string indent) const
{
   os << indent << "  Umean: " << std::endl;
   for(std::uint64_t d = 0; d < nmodes(); ++d)
      os << indent << "    U(" << d << ").colwise().mean: "
         << U(d).colwise().mean()
         << std::endl;

   return os;
}

Matrix::ConstBlockXpr SubModel::U(int f) const
{
   const Matrix &u = m_model.U(f); //force const
   return u.block(m_off.at(f), 0, m_dims.at(f), m_model.nlatent());
}

ConstVMatrixExprIterator<Matrix::ConstBlockXpr> SubModel::CVbegin(std::uint32_t mode) const
{
   return ConstVMatrixExprIterator<Matrix::ConstBlockXpr>(&m_model, m_off, m_dims, mode, 0);
}

ConstVMatrixExprIterator<Matrix::ConstBlockXpr> SubModel::CVend() const
{
   return ConstVMatrixExprIterator<Matrix::ConstBlockXpr>(m_model.nmodes());
}
} // end namespace smurff
<commit_msg>ENH: print model dims<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <chrono>
#include <memory>
#include <cmath>
#include <signal.h>

#include <SmurffCpp/Types.h>

#include <SmurffCpp/DataMatrices/Data.h>
#include <SmurffCpp/Utils/Distribution.h>

#include <SmurffCpp/Model.h>

#include <SmurffCpp/VMatrixIterator.hpp>
#include <SmurffCpp/ConstVMatrixIterator.hpp>
#include <SmurffCpp/VMatrixExprIterator.hpp>
#include <SmurffCpp/ConstVMatrixExprIterator.hpp>

#include <Utils/Error.h>
#include <SmurffCpp/Utils/SaveState.h>

namespace smurff {

Model::Model()
   : m_num_latent(-1), m_dims(0)
{
}

//num_latent - size of latent dimension
//dims - dimentions of train data
//init_model_type - samples initialization type
void Model::init(int num_latent, const PVec<>& dims, ModelInitTypes model_init_type, bool save_model, bool aggregate)
{
   size_t nmodes = dims.size();

   m_num_latent = num_latent;
   m_dims = dims;
   m_collect_aggr = aggregate;
   m_save_model = save_model;
   m_num_aggr = std::vector<int>(dims.size(), 0);

   m_factors.resize(nmodes);
   m_link_matrices.resize(nmodes);
   m_mus.resize(nmodes);

   for(size_t i = 0; i < nmodes; ++i)
   {
      Matrix& mat = m_factors.at(i);
      mat.resize(dims[i], m_num_latent);

      switch(model_init_type)
      {
      case ModelInitTypes::random:
         mat = Matrix::NullaryExpr(mat.rows(), mat.cols(), RandNormalGenerator());
         break;
      case ModelInitTypes::zero:
         mat.setZero();
         break;
      default:
         {
            THROWERROR("Invalid model init type");
         }
      }

      if (aggregate)
      {
         m_aggr_sum.push_back(Matrix::Zero(dims[i], m_num_latent));
         m_aggr_dot.push_back(Matrix::Zero(dims[i], m_num_latent * m_num_latent));
      }
   }

   Pcache.init(Array1D::Ones(m_num_latent));
}

Matrix &Model::getLinkMatrix(int mode)
{
   return m_link_matrices.at(mode);
}

Vector &Model::getMu(int mode)
{
   return m_mus.at(mode);
}

const Matrix &Model::getLinkMatrix(int mode) const
{
   return m_link_matrices.at(mode);
}

const Vector &Model::getMu(int mode) const
{
   return m_mus.at(mode);
}

double Model::predict(const PVec<> &pos) const
{
   if (nmodes() == 2)
   {
      return row(0, pos[0]).dot(row(1, pos[1]));
   }

   auto &P = Pcache.local();
   P.setOnes();
   for(uint32_t d = 0; d < nmodes(); ++d)
      P *= row(d, pos.at(d)).array();
   return P.sum();
}

const Matrix &Model::U(uint32_t f) const
{
   return m_factors.at(f);
}

Matrix &Model::U(uint32_t f)
{
   return m_factors[f];
}

VMatrixIterator<Matrix> Model::Vbegin(std::uint32_t mode)
{
   return VMatrixIterator<Matrix>(this, mode, 0);
}

VMatrixIterator<Matrix> Model::Vend()
{
   return VMatrixIterator<Matrix>(m_factors.size());
}

ConstVMatrixIterator<Matrix> Model::CVbegin(std::uint32_t mode) const
{
   return ConstVMatrixIterator<Matrix>(this, mode, 0);
}

ConstVMatrixIterator<Matrix> Model::CVend() const
{
   return ConstVMatrixIterator<Matrix>(m_factors.size());
}

Matrix::ConstRowXpr Model::row(int f, int i) const
{
   return U(f).row(i);
}

std::uint64_t Model::nmodes() const
{
   return m_factors.size();
}

int Model::nlatent() const
{
   return m_num_latent;
}

int Model::nsamples() const
{
   return std::accumulate(m_factors.begin(), m_factors.end(), 0,
      [](const int &a, const Matrix &b) { return a + b.rows(); });
}

const PVec<>& Model::getDims() const
{
   return m_dims;
}

SubModel Model::full()
{
   return SubModel(*this);
}

void Model::updateAggr(int m, int i)
{
   if (!m_collect_aggr) return;

   const auto &r = row(m, i);
   Matrix cov = (r.transpose() * r);
   m_aggr_sum.at(m).row(i) += r;
   m_aggr_dot.at(m).row(i) += Eigen::Map<Vector>(cov.data(), nlatent() * nlatent());
}

void Model::updateAggr(int m)
{
   m_num_aggr.at(m)++;
}

void Model::save(SaveState &sf) const
{
   sf.putModel(m_factors);
   for (std::uint64_t m = 0; m < nmodes(); ++m)
   {
      sf.putLinkMatrix(m, m_link_matrices.at(m));
      sf.putMu(m, m_mus.at(m));

      if (m_collect_aggr && m_save_aggr)
      {
         double n = m_num_aggr.at(m);

         const Matrix &Usum = m_aggr_sum.at(m);
         const Matrix &Uprod = m_aggr_dot.at(m);

         Matrix mu = Matrix::Zero(Usum.rows(), Usum.cols());
         // inverse of the covariance
         Matrix prec = Matrix::Zero(Uprod.rows(), Uprod.cols());

         // calculate real mu and Lambda
         for (int i = 0; i < U(m).rows(); i++)
         {
            Vector sum = Usum.row(i);
            Matrix prod = Eigen::Map<const Matrix>(Uprod.row(i).data(), nlatent(), nlatent());
            Matrix prec_i = ((prod - (sum.transpose() * sum / n)) / (n - 1)).inverse();

            prec.row(i) = Eigen::Map<Vector>(prec_i.data(), nlatent() * nlatent());
            mu.row(i) = sum / n;
         }

         sf.putPostMuLambda(m, mu, prec);
      }
   }
}

void Model::restore(const SaveState &sf, int skip_mode)
{
   unsigned nmodes = sf.getNModes();
   m_factors.clear();
   m_dims = PVec<>(nmodes);
   m_factors.resize(nmodes);

   for (std::uint64_t i = 0; i < nmodes; ++i)
   {
      if ((int)i != skip_mode)
      {
         auto &U = m_factors.at(i);
         sf.readModel(i, U);
         m_dims.at(i) = U.rows();
         m_num_latent = U.cols();
      }
      else
      {
         m_dims.at(i) = -1;
      }
   }

   m_link_matrices.resize(nmodes);
   m_mus.resize(nmodes);

   for(unsigned i=0; i<nmodes; ++i)
   {
      sf.readLinkMatrix(i, m_link_matrices.at(i));
      sf.readMu(i, m_mus.at(i));
   }

   Pcache.init(Array1D::Ones(m_num_latent));
}

std::ostream& Model::info(std::ostream &os, std::string indent) const
{
   os << indent << "Num-latents: " << m_num_latent << std::endl;
   os << indent << "Dimensions: " << m_dims << std::endl;

   return os;
}

std::ostream& Model::status(std::ostream &os, std::string indent) const
{
   os << indent << "  Umean: " << std::endl;
   for(std::uint64_t d = 0; d < nmodes(); ++d)
      os << indent << "    U(" << d << ").colwise().mean: "
         << U(d).colwise().mean()
         << std::endl;

   return os;
}

Matrix::ConstBlockXpr SubModel::U(int f) const
{
   const Matrix &u = m_model.U(f); //force const
   return u.block(m_off.at(f), 0, m_dims.at(f), m_model.nlatent());
}

ConstVMatrixExprIterator<Matrix::ConstBlockXpr> SubModel::CVbegin(std::uint32_t mode) const
{
   return ConstVMatrixExprIterator<Matrix::ConstBlockXpr>(&m_model, m_off, m_dims, mode, 0);
}

ConstVMatrixExprIterator<Matrix::ConstBlockXpr> SubModel::CVend() const
{
   return ConstVMatrixExprIterator<Matrix::ConstBlockXpr>(m_model.nmodes());
}
} // end namespace smurff
<|endoftext|>