<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: backendlayerhelper.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 03:36:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_
#define CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_

#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_XLAYERCONTENTDESCRIBER_HPP_
#include <com/sun/star/configuration/backend/XLayerContentDescriber.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif // _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_

#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#ifndef _CPPUHELPER_COMPBASE2_HXX_
#include <cppuhelper/compbase2.hxx>
#endif // _CPPUHELPER_COMPBASE2_HXX_

namespace configmgr { namespace backendhelper {

namespace css = com::sun::star ;
namespace uno = css::uno ;
namespace lang = css::lang ;
namespace backend = css::configuration::backend ;
//------------------------------------------------------------------------------

typedef cppu::WeakComponentImplHelper2<backend::XLayerContentDescriber,
                                       lang::XServiceInfo> BackendBase ;

/**
  *  Implements the LayerContentDescriber service.
  *  Describes a set of configuration data to an XLayerHandler
  *  Object
  */
class BackendLayerHelper : public BackendBase {
public :
    /**
     Service constructor from a service factory.
     @param xContext   component context
    */
    BackendLayerHelper(const uno::Reference<uno::XComponentContext>& xContext) ;

    /** Destructor */
    ~BackendLayerHelper(void) ;

    // XServiceInfo
    virtual rtl::OUString SAL_CALL
        getImplementationName(  )
        throw (uno::RuntimeException) ;

    virtual sal_Bool SAL_CALL
        supportsService( const rtl::OUString& aServiceName )
        throw (uno::RuntimeException) ;

    virtual uno::Sequence<rtl::OUString> SAL_CALL
        getSupportedServiceNames(  )
        throw (uno::RuntimeException) ;

    //XLayerContentDescriber
    virtual void SAL_CALL
        describeLayer( const uno::Reference< backend::XLayerHandler >& xHandler,
                        const uno::Sequence< backend::PropertyInfo >& aPropertyInfos )
        throw (lang::NullPointerException,
               backend::MalformedDataException,
               uno::RuntimeException);

    /**
     Provides the implementation name.

     @return   implementation name
    */
    static rtl::OUString SAL_CALL getBackendLayerHelperName(void) ;
    /**
     Provides the supported services names

     @return   service names
    */
    static uno::Sequence<rtl::OUString> SAL_CALL getBackendLayerHelperServiceNames(void) ;
private:
    osl::Mutex mMutex;

} ;
//------------------------------------------------------------------------------
class OONode;
class OOProperty;

/**
   Base class for representing OO properties and nodes
*/
class IOONode
{
public:
    virtual OONode* getComposite(){return NULL;}
    virtual ~IOONode(){};
    virtual OOProperty* asOOProperty(){return NULL;}
    rtl::OUString getName(){return mName;}
    void  setName(const rtl::OUString& sName){mName = sName;}
protected:
    IOONode(const rtl::OUString& sName);
private:
    rtl::OUString mName;
};
//------------------------------------------------------------------------------
class OONode :public IOONode
{
public:

    OONode(const rtl::OUString& sName);
    OONode();
    ~OONode();

    IOONode* addChild(IOONode* aChild);
    OONode* getComposite(){return this;}
    const std::vector<IOONode*>& getChildren();
    IOONode* getChild(const rtl::OUString& aChildName);

private:
    typedef std::vector<IOONode*> ChildList;
    ChildList mChildList;
};
//------------------------------------------------------------------------------
class OOProperty :public IOONode
{
public:
    OOProperty(const rtl::OUString& sName,
               const rtl::OUString& sPropType,
               const uno::Any& aPropValue,
               sal_Bool bProtected);
    ~OOProperty(){};

    const rtl::OUString& getType(){return mPropType;}
    uno::Any getValue(){return mPropValue;}
    sal_Bool isProtected(){return mbProtected;}
    OOProperty* asOOProperty(){return this;}

private:
    rtl::OUString mPropType;
    uno::Any mPropValue;
    sal_Bool mbProtected;
};
//------------------------------------------------------------------------------

} } // configmgr.backendhelper

#endif // CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.3.130); FILE MERGED 2008/04/01 15:06:40 thb 1.3.130.3: #i85898# Stripping all external header guards 2008/04/01 12:27:20 thb 1.3.130.2: #i85898# Stripping all external header guards 2008/03/31 12:22:41 rt 1.3.130.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: backendlayerhelper.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_
#define CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_

#include <com/sun/star/configuration/backend/XLayerContentDescriber.hpp>

#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <cppuhelper/compbase2.hxx>

namespace configmgr { namespace backendhelper {

namespace css = com::sun::star ;
namespace uno = css::uno ;
namespace lang = css::lang ;
namespace backend = css::configuration::backend ;
//------------------------------------------------------------------------------

typedef cppu::WeakComponentImplHelper2<backend::XLayerContentDescriber,
                                       lang::XServiceInfo> BackendBase ;

/**
  *  Implements the LayerContentDescriber service.
  *  Describes a set of configuration data to an XLayerHandler
  *  Object
  */
class BackendLayerHelper : public BackendBase {
public :
    /**
     Service constructor from a service factory.
     @param xContext   component context
    */
    BackendLayerHelper(const uno::Reference<uno::XComponentContext>& xContext) ;

    /** Destructor */
    ~BackendLayerHelper(void) ;

    // XServiceInfo
    virtual rtl::OUString SAL_CALL
        getImplementationName(  )
        throw (uno::RuntimeException) ;

    virtual sal_Bool SAL_CALL
        supportsService( const rtl::OUString& aServiceName )
        throw (uno::RuntimeException) ;

    virtual uno::Sequence<rtl::OUString> SAL_CALL
        getSupportedServiceNames(  )
        throw (uno::RuntimeException) ;

    //XLayerContentDescriber
    virtual void SAL_CALL
        describeLayer( const uno::Reference< backend::XLayerHandler >& xHandler,
                        const uno::Sequence< backend::PropertyInfo >& aPropertyInfos )
        throw (lang::NullPointerException,
               backend::MalformedDataException,
               uno::RuntimeException);

    /**
     Provides the implementation name.

     @return   implementation name
    */
    static rtl::OUString SAL_CALL getBackendLayerHelperName(void) ;
    /**
     Provides the supported services names

     @return   service names
    */
    static uno::Sequence<rtl::OUString> SAL_CALL getBackendLayerHelperServiceNames(void) ;
private:
    osl::Mutex mMutex;

} ;
//------------------------------------------------------------------------------
class OONode;
class OOProperty;

/**
   Base class for representing OO properties and nodes
*/
class IOONode
{
public:
    virtual OONode* getComposite(){return NULL;}
    virtual ~IOONode(){};
    virtual OOProperty* asOOProperty(){return NULL;}
    rtl::OUString getName(){return mName;}
    void  setName(const rtl::OUString& sName){mName = sName;}
protected:
    IOONode(const rtl::OUString& sName);
private:
    rtl::OUString mName;
};
//------------------------------------------------------------------------------
class OONode :public IOONode
{
public:

    OONode(const rtl::OUString& sName);
    OONode();
    ~OONode();

    IOONode* addChild(IOONode* aChild);
    OONode* getComposite(){return this;}
    const std::vector<IOONode*>& getChildren();
    IOONode* getChild(const rtl::OUString& aChildName);

private:
    typedef std::vector<IOONode*> ChildList;
    ChildList mChildList;
};
//------------------------------------------------------------------------------
class OOProperty :public IOONode
{
public:
    OOProperty(const rtl::OUString& sName,
               const rtl::OUString& sPropType,
               const uno::Any& aPropValue,
               sal_Bool bProtected);
    ~OOProperty(){};

    const rtl::OUString& getType(){return mPropType;}
    uno::Any getValue(){return mPropValue;}
    sal_Bool isProtected(){return mbProtected;}
    OOProperty* asOOProperty(){return this;}

private:
    rtl::OUString mPropType;
    uno::Any mPropValue;
    sal_Bool mbProtected;
};
//------------------------------------------------------------------------------

} } // configmgr.backendhelper

#endif // CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_

<|endoftext|>


<commit_before>/***************************************************************************
*   Copyright (C) 2005-2011 by the FIFE team                              *
*   http://www.fifengine.net                                              *
*   This file is part of FIFE.                                            *
*                                                                         *
*   FIFE 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 Street, Fifth Floor, Boston, MA  02110-1301  USA          *
***************************************************************************/

// Standard C++ library includes

// 3rd party library includes

// FIFE includes
// These includes are split up in two parts, separated by one empty line
// First block: files included from the FIFE root src directory
// Second block: files included from the same folder
#include "ext/tinyxml/fife_tinyxml.h"
#include "model/structures/map.h"
#include "model/structures/layer.h"
#include "model/structures/instance.h"
#include "model/metamodel/object.h"
#include "model/metamodel/grids/cellgrid.h"
#include "util/structures/point.h"
#include "util/structures/rect.h"
#include "view/visual.h"
#include "view/camera.h"

#include "mapsaver.h"

namespace FIFE {
    static Logger _log(LM_NATIVE_SAVERS);

    MapSaver::MapSaver() {
        //m_objectSaver = new ObjectSaver();
        //m_animationSaver = new AnimationSaver();
        //m_atlasSaver = new AtlasSaver();
    }

    MapSaver::~MapSaver()
    {

    }

    void MapSaver::setObjectSaver(const FIFE::ObjectSaverPtr& objectSaver) {
        m_objectSaver = objectSaver;
    }

    void MapSaver::setAnimationSaver(const FIFE::AnimationSaverPtr& animationSaver) {
        m_animationSaver = animationSaver;
    }

    void MapSaver::setAtlasSaver(const FIFE::AtlasSaverPtr& atlasSaver) {
        m_atlasSaver = atlasSaver;
    }

    void MapSaver::save(const Map& map, const std::string& filename) {
        TiXmlDocument doc(filename);

        if (doc.Error())
        {
            // log error and drop out of save
            std::ostringstream oss;
            oss << " Failed to open"
                << filename
                << " : " << __FILE__
                << " [" << __LINE__ << "]"
                << std::endl;
            FL_ERR(_log, oss.str());
            return;
        }

        // add xml declaration
        TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "ascii", "");
        doc.LinkEndChild(decl);

        // add map element
        TiXmlElement* mapElement = new TiXmlElement("map");
        mapElement->SetAttribute("id", map.getId());
        mapElement->SetAttribute("format", "1.0");
        doc.LinkEndChild(mapElement);

        typedef std::list<Layer*> LayerList;
        LayerList layers = map.getLayers();
        for (LayerList::iterator iter = layers.begin(); iter != layers.end(); ++iter)
        {
            TiXmlElement *layerElement = new TiXmlElement("layer");
            CellGrid* grid = (*iter)->getCellGrid();
            layerElement->SetAttribute("id", (*iter)->getId());
            layerElement->SetDoubleAttribute("x_offset", grid->getXShift());
            layerElement->SetDoubleAttribute("y_offset", grid->getYShift());
            layerElement->SetDoubleAttribute("z_offset", grid->getZShift());
            layerElement->SetDoubleAttribute("x_scale", grid->getXScale());
            layerElement->SetDoubleAttribute("y_scale", grid->getYScale());
            layerElement->SetDoubleAttribute("rotation", grid->getRotation());
            layerElement->SetAttribute("grid_type", grid->getType());
            layerElement->SetAttribute("transparency", (*iter)->getLayerTransparency());

            std::string pathingStrategy;
            switch ((*iter)->getPathingStrategy())
            {
                case CELL_EDGES_ONLY:
                {
                    pathingStrategy = "cell_edges_only";
                }
                break;
                case CELL_EDGES_AND_DIAGONALS:
                {
                    pathingStrategy = "cell_edges_and_diagonals";
                }
                break;
                case FREEFORM:
                {
                    pathingStrategy = "freeform";
                }
                break;
                default:
                {
                    pathingStrategy = "cell_edges_only";
                }
                break;
            }
            layerElement->SetAttribute("pathing", pathingStrategy);

            // add layer to document
            mapElement->LinkEndChild(layerElement);

            // add instances tag to document
            TiXmlElement* instancesElement = new TiXmlElement("instances");
            layerElement->LinkEndChild(instancesElement);

            typedef std::vector<Instance*> InstancesContainer;
            InstancesContainer instances = (*iter)->getInstances();
            for (InstancesContainer::iterator iter = instances.begin(); iter != instances.end(); ++iter)
            {
                // create instance element
                TiXmlElement* instanceElement = new TiXmlElement("i");

                Object* obj = (*iter)->getObject();
                if (!obj->getNamespace().empty())
                {
                    instanceElement->SetAttribute("ns", obj->getNamespace());
                }

                if (!(*iter)->getId().empty())
                {
                    instanceElement->SetAttribute("id", (*iter)->getId());
                }

                instanceElement->SetAttribute("o", obj->getId());

                ExactModelCoordinate position = (*iter)->getLocationRef().getExactLayerCoordinates();
                instanceElement->SetDoubleAttribute("x", position.x);
                instanceElement->SetDoubleAttribute("y", position.y);
                instanceElement->SetDoubleAttribute("z", position.z);
                instanceElement->SetAttribute("r", (*iter)->getRotation());

                if ((*iter)->isBlocking())
                {
                    instanceElement->SetAttribute("blocking", (*iter)->isBlocking());
                }

                InstanceVisual* instanceVisual = (*iter)->getVisual<InstanceVisual>();
                instanceElement->SetAttribute("stackpos", instanceVisual->getStackPosition());

                instancesElement->LinkEndChild(instanceElement);
            }
        }

        typedef std::vector<Camera*> CameraContainer;
        CameraContainer cameras = map.getCameras();
        for (CameraContainer::iterator iter = cameras.begin(); iter != cameras.end(); ++iter)
        {
            if ((*iter)->getLocationRef().getMap()->getId() == map.getId())
            {
                TiXmlElement* cameraElement = new TiXmlElement("camera");

                cameraElement->SetAttribute("id", (*iter)->getId());
                cameraElement->SetAttribute("ref_layer_id", (*iter)->getLocation().getLayer()->getId());
                cameraElement->SetDoubleAttribute("zoom", (*iter)->getZoom());
                cameraElement->SetDoubleAttribute("tilt", (*iter)->getTilt());
                cameraElement->SetDoubleAttribute("rotation", (*iter)->getRotation());

                Rect viewport = (*iter)->getViewPort();
                std::ostringstream viewportString;
                viewportString << viewport.x << ","
                               << viewport.y << ","
                               << viewport.w << ","
                               << viewport.h;

                cameraElement->SetAttribute("viewport", viewportString.str());

                Point p = (*iter)->getCellImageDimensions();
                cameraElement->SetAttribute("ref_cell_width", p.x);
                cameraElement->SetAttribute("ref_cell_height", p.y);

                std::vector<float> lightingColor = (*iter)->getLightingColor();
                bool writeLightingColor = false;
                for (uint32_t i=0; i < lightingColor.size(); ++i)
                {
                    if (lightingColor[i] < 1.0)
                    {
                        writeLightingColor = true;
                        break;
                    }
                }

                if (writeLightingColor)
                {
                    std::ostringstream lightingColorString;
                    for (uint32_t i=0; i < lightingColor.size(); ++i)
                    {
                        if (i > 0)
                        {
                            lightingColorString << ",";
                        }

                        lightingColorString << lightingColor[i];

                        cameraElement->SetAttribute("light_color", lightingColorString.str());
                    }
                }

                mapElement->LinkEndChild(cameraElement);
            }
        }
    }
}<commit_msg>quick fix to add in saving of the xml file. [t:491]<commit_after>/***************************************************************************
*   Copyright (C) 2005-2011 by the FIFE team                              *
*   http://www.fifengine.net                                              *
*   This file is part of FIFE.                                            *
*                                                                         *
*   FIFE 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 Street, Fifth Floor, Boston, MA  02110-1301  USA          *
***************************************************************************/

// Standard C++ library includes

// 3rd party library includes

// FIFE includes
// These includes are split up in two parts, separated by one empty line
// First block: files included from the FIFE root src directory
// Second block: files included from the same folder
#include "ext/tinyxml/fife_tinyxml.h"
#include "model/structures/map.h"
#include "model/structures/layer.h"
#include "model/structures/instance.h"
#include "model/metamodel/object.h"
#include "model/metamodel/grids/cellgrid.h"
#include "util/structures/point.h"
#include "util/structures/rect.h"
#include "view/visual.h"
#include "view/camera.h"

#include "mapsaver.h"

namespace FIFE {
    static Logger _log(LM_NATIVE_SAVERS);

    MapSaver::MapSaver() {
        //m_objectSaver = new ObjectSaver();
        //m_animationSaver = new AnimationSaver();
        //m_atlasSaver = new AtlasSaver();
    }

    MapSaver::~MapSaver()
    {

    }

    void MapSaver::setObjectSaver(const FIFE::ObjectSaverPtr& objectSaver) {
        m_objectSaver = objectSaver;
    }

    void MapSaver::setAnimationSaver(const FIFE::AnimationSaverPtr& animationSaver) {
        m_animationSaver = animationSaver;
    }

    void MapSaver::setAtlasSaver(const FIFE::AtlasSaverPtr& atlasSaver) {
        m_atlasSaver = atlasSaver;
    }

    void MapSaver::save(const Map& map, const std::string& filename) {
        TiXmlDocument doc;

        // add xml declaration
        TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "ascii", "");
        doc.LinkEndChild(decl);

        // add map element
        TiXmlElement* mapElement = new TiXmlElement("map");
        mapElement->SetAttribute("id", map.getId());
        mapElement->SetAttribute("format", "1.0");
        doc.LinkEndChild(mapElement);

        typedef std::list<Layer*> LayerList;
        LayerList layers = map.getLayers();
        for (LayerList::iterator iter = layers.begin(); iter != layers.end(); ++iter)
        {
            TiXmlElement *layerElement = new TiXmlElement("layer");
            CellGrid* grid = (*iter)->getCellGrid();
            layerElement->SetAttribute("id", (*iter)->getId());
            layerElement->SetDoubleAttribute("x_offset", grid->getXShift());
            layerElement->SetDoubleAttribute("y_offset", grid->getYShift());
            layerElement->SetDoubleAttribute("z_offset", grid->getZShift());
            layerElement->SetDoubleAttribute("x_scale", grid->getXScale());
            layerElement->SetDoubleAttribute("y_scale", grid->getYScale());
            layerElement->SetDoubleAttribute("rotation", grid->getRotation());
            layerElement->SetAttribute("grid_type", grid->getType());
            layerElement->SetAttribute("transparency", (*iter)->getLayerTransparency());

            std::string pathingStrategy;
            switch ((*iter)->getPathingStrategy())
            {
                case CELL_EDGES_ONLY:
                {
                    pathingStrategy = "cell_edges_only";
                }
                break;
                case CELL_EDGES_AND_DIAGONALS:
                {
                    pathingStrategy = "cell_edges_and_diagonals";
                }
                break;
                case FREEFORM:
                {
                    pathingStrategy = "freeform";
                }
                break;
                default:
                {
                    pathingStrategy = "cell_edges_only";
                }
                break;
            }
            layerElement->SetAttribute("pathing", pathingStrategy);

            // add layer to document
            mapElement->LinkEndChild(layerElement);

            // add instances tag to document
            TiXmlElement* instancesElement = new TiXmlElement("instances");
            layerElement->LinkEndChild(instancesElement);

            typedef std::vector<Instance*> InstancesContainer;
            InstancesContainer instances = (*iter)->getInstances();
            for (InstancesContainer::iterator iter = instances.begin(); iter != instances.end(); ++iter)
            {
                // create instance element
                TiXmlElement* instanceElement = new TiXmlElement("i");

                Object* obj = (*iter)->getObject();
                if (!obj->getNamespace().empty())
                {
                    instanceElement->SetAttribute("ns", obj->getNamespace());
                }

                if (!(*iter)->getId().empty())
                {
                    instanceElement->SetAttribute("id", (*iter)->getId());
                }

                instanceElement->SetAttribute("o", obj->getId());

                ExactModelCoordinate position = (*iter)->getLocationRef().getExactLayerCoordinates();
                instanceElement->SetDoubleAttribute("x", position.x);
                instanceElement->SetDoubleAttribute("y", position.y);
                instanceElement->SetDoubleAttribute("z", position.z);
                instanceElement->SetAttribute("r", (*iter)->getRotation());

                if ((*iter)->isBlocking())
                {
                    instanceElement->SetAttribute("blocking", (*iter)->isBlocking());
                }

                InstanceVisual* instanceVisual = (*iter)->getVisual<InstanceVisual>();
                instanceElement->SetAttribute("stackpos", instanceVisual->getStackPosition());

                instancesElement->LinkEndChild(instanceElement);
            }
        }

        typedef std::vector<Camera*> CameraContainer;
        CameraContainer cameras = map.getCameras();
        for (CameraContainer::iterator iter = cameras.begin(); iter != cameras.end(); ++iter)
        {
            if ((*iter)->getLocationRef().getMap()->getId() == map.getId())
            {
                TiXmlElement* cameraElement = new TiXmlElement("camera");

                cameraElement->SetAttribute("id", (*iter)->getId());
                cameraElement->SetAttribute("ref_layer_id", (*iter)->getLocation().getLayer()->getId());
                cameraElement->SetDoubleAttribute("zoom", (*iter)->getZoom());
                cameraElement->SetDoubleAttribute("tilt", (*iter)->getTilt());
                cameraElement->SetDoubleAttribute("rotation", (*iter)->getRotation());

                Rect viewport = (*iter)->getViewPort();
                std::ostringstream viewportString;
                viewportString << viewport.x << ","
                               << viewport.y << ","
                               << viewport.w << ","
                               << viewport.h;

                cameraElement->SetAttribute("viewport", viewportString.str());

                Point p = (*iter)->getCellImageDimensions();
                cameraElement->SetAttribute("ref_cell_width", p.x);
                cameraElement->SetAttribute("ref_cell_height", p.y);

                std::vector<float> lightingColor = (*iter)->getLightingColor();
                bool writeLightingColor = false;
                for (uint32_t i=0; i < lightingColor.size(); ++i)
                {
                    if (lightingColor[i] < 1.0)
                    {
                        writeLightingColor = true;
                        break;
                    }
                }

                if (writeLightingColor)
                {
                    std::ostringstream lightingColorString;
                    for (uint32_t i=0; i < lightingColor.size(); ++i)
                    {
                        if (i > 0)
                        {
                            lightingColorString << ",";
                        }

                        lightingColorString << lightingColor[i];

                        cameraElement->SetAttribute("light_color", lightingColorString.str());
                    }
                }

                mapElement->LinkEndChild(cameraElement);
            }
        }

        // save the map xml file
        doc.SaveFile(filename);
    }
}<|endoftext|>


<commit_before>#include <iostream>
#include <cstring>
using namespace std;

void swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

void reverse(int *a, int start, int end)
{
	for (int i = 0; i < (end - start + 1) / 2; i++) {
		swap(a[start + i], a[end - i]);
	}
}

void print(int *a, int start, int end)
{
	for (int i = start; i <= end; i++) {
		cout << a[i] << " ";
	}
	cout << endl;
}

//Not inplace but doesn't need extra space
int partition_1(int *a, int start, int end)
{
	int p = start;
	for (int i = start + 1; i <= end; i++) {
		if (a[i] < a[start]) {
			swap(a[++p], a[i]);
		}
	}
	swap(a[p], a[start]);
	return p;
}

//Inplace but need extra space O(n)
int partition_2(int *a, int start, int end)
{
	int n = end - start + 1;
	int *temp = new int[n];
	int i = 0, j = n - 1;
	for (int k = start + 1; k <= end; k++) {
		if (a[k] < a[start]) {
			temp[i++] = a[k];
		}
		else {
			temp[j--] = a[k];
		}
	}
	temp[i] = a[start];
	memcpy(a + start, temp, n * sizeof(int));
	reverse(a, start + i + 1, end);
	delete [] temp;
	return start + i;
}

void quicksort(int *a, int start, int end)
{
	if (start < end) {
		int mid = partition_2(a, start, end);
		quicksort(a, start, mid - 1);
		quicksort(a, mid + 1, end);
		print(a, start, end);
	}
}

int main()
{
	int n;
	cin >> n;
	int *a = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	quicksort(a, 0, n - 1);
	// print(a, 0, n - 1);
	delete [] a;
	return 0;
}<commit_msg>Update comments.<commit_after>#include <iostream>
#include <cstring>
using namespace std;

void swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

void reverse(int *a, int start, int end)
{
	for (int i = 0; i < (end - start + 1) / 2; i++) {
		swap(a[start + i], a[end - i]);
	}
}

void print(int *a, int start, int end)
{
	for (int i = start; i <= end; i++) {
		cout << a[i] << " ";
	}
	cout << endl;
}

//Inplace but not stable
int partition_1(int *a, int start, int end)
{
	int p = start;
	for (int i = start + 1; i <= end; i++) {
		if (a[i] < a[start]) {
			swap(a[++p], a[i]);
		}
	}
	swap(a[p], a[start]);
	return p;
}

//Stable but not inplace
int partition_2(int *a, int start, int end)
{
	int n = end - start + 1;
	int *temp = new int[n];
	int i = 0, j = n - 1;
	for (int k = start + 1; k <= end; k++) {
		if (a[k] < a[start]) {
			temp[i++] = a[k];
		}
		else {
			temp[j--] = a[k];
		}
	}
	temp[i] = a[start];
	memcpy(a + start, temp, n * sizeof(int));
	reverse(a, start + i + 1, end);
	delete [] temp;
	return start + i;
}

void quicksort(int *a, int start, int end)
{
	if (start < end) {
		int mid = partition_2(a, start, end);
		quicksort(a, start, mid - 1);
		quicksort(a, mid + 1, end);
		print(a, start, end);
	}
}

int main()
{
	int n;
	cin >> n;
	int *a = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	quicksort(a, 0, n - 1);
	// print(a, 0, n - 1);
	delete [] a;
	return 0;
}
<|endoftext|>


<commit_before>#include <boost/python.hpp>
#include "ModelInterface.h"
#include "pyToCppModelInterfaceCache.h"

#include <boost/python/stl_iterator.hpp>
#include <iostream>
#include <stdexcept>
#include <boost/python/numeric.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <numpy/noprefix.h>

namespace threeML {

template<typename T>
inline
std::vector<T> to_std_vector(const boost::python::object &iterable) {
  return std::vector<T>(boost::python::stl_input_iterator<T>(iterable),
                        boost::python::stl_input_iterator<T>());
}

void pyToCppModelInterfaceCache::setPtsSourceSpectrum(const int id, const numeric::array& spectrum)
{

  // These are both n_points in size

  PyArrayObject* spectrum__ = (PyArrayObject*) spectrum.ptr();

  unsigned int n_energies = (unsigned int) *(spectrum__->dimensions);

  double* spectrum_ = (double *) spectrum__->data;

  m_ptsSources[id].assign(spectrum_, spectrum_ + n_energies);

}

void pyToCppModelInterfaceCache::setPtsSourcePosition(const int id, const float lon, const float lat)
{

  m_ptsSourcesPos[id] = SkyCoord(lon, lat);

}

void pyToCppModelInterfaceCache::setExtSourceBoundaries(const int id, const float lon_min, const float lon_max,
                                                        const float lat_min, const float lat_max)
{

  BoundingBox this_boundingBox;

  this_boundingBox.lon_min = lon_min;
  this_boundingBox.lon_max = lon_max;
  this_boundingBox.lat_min = lat_min;
  this_boundingBox.lat_max = lat_max;

  m_boundingBoxes[id] = this_boundingBox;

}

void pyToCppModelInterfaceCache::setExtSourceCube(const int id, const numeric::array &cube,
                                                  const numeric::array &lon, const numeric::array &lat)
{

  // Add an extended source to the cache (a map)

  PyArrayObject* cube__ = (PyArrayObject*) cube.ptr();

  unsigned int n_points = (unsigned int) *(cube__->dimensions);
  unsigned int n_energies = (unsigned int) *(cube__->dimensions+1);

  // This is n_points * n_energies in size

  double* cube_ = (double *) cube__->data;

  // These are both n_points in size

  double* lon_ = (double *) ((PyArrayObject*) lon.ptr())->data;
  double* lat_ = (double *) ((PyArrayObject*) lat.ptr())->data;

  ExtSrcCube this_srcCube;

  for(unsigned int i=0; i < n_points; ++i)
  {

    float this_lon = (float) lon_[i];
    float this_lat = (float) lat_[i];

    SkyCoord this_coord(this_lon, this_lat);

    // A little of pointer algebra

    int this_data_start = i * n_energies;
    int this_data_stop = this_data_start + n_energies;

    // Note how this construct avoid the double copy which would
    // occur if we were to first create a vector and then
    // copy it into a standard map. Here instead the operator
    // [] creates an empty vector, which is then filled with
    // the assign method

    this_srcCube[this_coord].assign(cube_ + this_data_start, cube_ + this_data_stop);

  }

  // Finally add to the map

  m_extSources[id] = this_srcCube;

}

bool pyToCppModelInterfaceCache::isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
  return true;
}

int pyToCppModelInterfaceCache::getNumberOfPointSources() const {

  return m_ptsSourcesPos.size();

}

void pyToCppModelInterfaceCache::getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {

  try {

    SkyCoord this_position = m_ptsSourcesPos.at(srcid);
    *j2000_ra = this_position.first;
    *j2000_dec = this_position.second;

  } catch (...) {

    std::stringstream name;

    name << "Point source " << srcid << " not found in position cache";

    throw std::runtime_error(name.str());

  }

}

void pyToCppModelInterfaceCache::reset() {

  //Empty the cache

  m_extSources.clear();
  m_ptsSources.clear();
  /*
  m_boundingBoxes.clear();
  m_nExtSources = 0;
  m_nPtSources = 0;*/

}

std::vector<double>
pyToCppModelInterfaceCache::getPointSourceFluxes(int srcid, std::vector<double> energies) const {

  if (m_ptsSources.count(srcid) == 0)
  {
    // This happens during the construction of LikeHAWC because there is a energy reweighting
    // At that moment the cache is still empty, so let's just return the energy array which
    // has the right size.

    /*
    std::stringstream name;

    name << "Point source " << srcid << " not found in spectrum cache";

    throw std::runtime_error(name.str());*/

    std::cerr << "Point source " << srcid << " not found in spectrum cache" << std::endl;

    return energies;

  } else {

    return m_ptsSources.at(srcid);

  }

}

int pyToCppModelInterfaceCache::getNumberOfExtendedSources() const {

  // We use the size of bounding boxes and not of m_extSources because the latter
  // could get filled in a second moment
  return m_boundingBoxes.size();

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                               std::vector<double> energies) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes_test(int srcid, double j2000_ra, double j2000_dec) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::string pyToCppModelInterfaceCache::getPointSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Point source " << srcid;

  return name.str();
}

std::string pyToCppModelInterfaceCache::getExtendedSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Extended source " << srcid;

  return name.str();
}

void pyToCppModelInterfaceCache::getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                                        double *j2000_ra_max,
                                                        double *j2000_dec_min,
                                                        double *j2000_dec_max) const {

  const BoundingBox *this_boundingBox = &m_boundingBoxes.at(srcid);

  *j2000_ra_min = this_boundingBox->lon_min;
  *j2000_ra_max = this_boundingBox->lon_max;
  *j2000_dec_min = this_boundingBox->lat_min;
  *j2000_dec_max = this_boundingBox->lat_max;

}

}

using namespace threeML;
using namespace boost::python;

//This is needed to wrap the interface (i.e., all methods are virtual)
//contained in ModelInterface.h
struct ModelInterfaceCacheWrap: ModelInterface, wrapper<ModelInterface> {
  int getNumberOfPointSources() const { return this->get_override("getNumberOfPointSources")(); }

  void getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {
    this->get_override("getPointSourcePosition")();
  }

  std::vector<double> getPointSourceFluxes(int srcid, std::vector<double> energies) const {
    return this->get_override("getPointSourceFluxes")();
  }

  std::string getPointSourceName(int srcid) const { return this->get_override("getPointSourceName")(); }

  int getNumberOfExtendedSources() const { return this->get_override("getNumberOfExtendedSources")(); }

  std::vector<double> getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                              std::vector<double> energies) const {
    return this->get_override("getExtendedSourceFluxes")();
  }

  std::string getExtendedSourceName(int srcid) const { return this->get_override("getExtendedSourceName")(); }

  bool isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
    return this->get_override("isInsideAnyExtendedSource")();
  }

  void getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                   double *j2000_ra_max,
                                   double *j2000_dec_min,
                                   double *j2000_dec_max) const { this->get_override("getExtendedSourceBoundaries")(); }
};

template<class T>
struct VecToList {
  static PyObject *convert(const std::vector<T> &vec) {
    boost::python::list *l = new boost::python::list();

    for (size_t i = 0; i < vec.size(); i++)
      (*l).append(vec[i]);

    return l->ptr();
  }
};

BOOST_PYTHON_MODULE (pyModelInterfaceCache) {
  //hello
  to_python_converter<std::vector<double, std::allocator<double> >, VecToList<double> >();

  class_<ModelInterfaceCacheWrap, boost::noncopyable>("ModelInterface")
      .def("getNumberOfPointSources", pure_virtual(&ModelInterface::getNumberOfPointSources))
      .def("getPointSourcePosition", pure_virtual(&ModelInterface::getPointSourcePosition))
      .def("getPointSourceFluxes", pure_virtual(&ModelInterface::getPointSourceFluxes))
      .def("getPointSourceName", pure_virtual(&ModelInterface::getPointSourceName))
      .def("getNumberOfExtendedSources", pure_virtual(&ModelInterface::getNumberOfExtendedSources))
      .def("getExtendedSourceFluxes", pure_virtual(&ModelInterface::getExtendedSourceFluxes))
      .def("getExtendedSourceName", pure_virtual(&ModelInterface::getExtendedSourceName))
      .def("isInsideAnyExtendedSource", pure_virtual(&ModelInterface::isInsideAnyExtendedSource))
      .def("getExtendedSourceBoundaries", pure_virtual(&ModelInterface::getExtendedSourceBoundaries));

  numeric::array::set_module_and_type("numpy", "ndarray");

  class_<pyToCppModelInterfaceCache, bases<ModelInterface> >("pyToCppModelInterfaceCache", init< >())
      .def("getNumberOfPointSources", &pyToCppModelInterfaceCache::getNumberOfPointSources)
      .def("getPointSourcePosition", &pyToCppModelInterfaceCache::getPointSourcePosition)
      .def("getPointSourceFluxes", &pyToCppModelInterfaceCache::getPointSourceFluxes)
      .def("getPointSourceName", &pyToCppModelInterfaceCache::getPointSourceName)
      .def("getNumberOfExtendedSources", &pyToCppModelInterfaceCache::getNumberOfExtendedSources)
      .def("getExtendedSourceFluxes", &pyToCppModelInterfaceCache::getExtendedSourceFluxes)
      .def("getExtendedSourceName", &pyToCppModelInterfaceCache::getExtendedSourceName)
      .def("isInsideAnyExtendedSource", &pyToCppModelInterfaceCache::isInsideAnyExtendedSource)
      .def("getExtendedSourceBoundaries", &pyToCppModelInterfaceCache::getExtendedSourceBoundaries)
      .def("setExtSourceBoundaries", &pyToCppModelInterfaceCache::setExtSourceBoundaries)
      .def("setExtSourceCube",&pyToCppModelInterfaceCache::setExtSourceCube)
      .def("getExtendedSourceFluxes_test",&pyToCppModelInterfaceCache::getExtendedSourceFluxes_test)
      .def("reset",&pyToCppModelInterfaceCache::reset)
      .def("setPtsSourceSpectrum",&pyToCppModelInterfaceCache::setPtsSourceSpectrum)
      .def("setPtsSourcePosition",&pyToCppModelInterfaceCache::setPtsSourcePosition);
}
<commit_msg>Update pyToCppModelInterfaceCache.cxx<commit_after>#include <boost/python.hpp>
#include "ModelInterface.h"
#include "pyToCppModelInterfaceCache.h"

#include <boost/python/stl_iterator.hpp>
#include <iostream>
#include <stdexcept>
#include <boost/python/numeric.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <numpy/noprefix.h>

namespace threeML {

template<typename T>
inline
std::vector<T> to_std_vector(const boost::python::object &iterable) {
  return std::vector<T>(boost::python::stl_input_iterator<T>(iterable),
                        boost::python::stl_input_iterator<T>());
}

void pyToCppModelInterfaceCache::setPtsSourceSpectrum(const int id, const boost::numeric::array& spectrum)
{

  // These are both n_points in size

  PyArrayObject* spectrum__ = (PyArrayObject*) spectrum.ptr();

  unsigned int n_energies = (unsigned int) *(spectrum__->dimensions);

  double* spectrum_ = (double *) spectrum__->data;

  m_ptsSources[id].assign(spectrum_, spectrum_ + n_energies);

}

void pyToCppModelInterfaceCache::setPtsSourcePosition(const int id, const float lon, const float lat)
{

  m_ptsSourcesPos[id] = SkyCoord(lon, lat);

}

void pyToCppModelInterfaceCache::setExtSourceBoundaries(const int id, const float lon_min, const float lon_max,
                                                        const float lat_min, const float lat_max)
{

  BoundingBox this_boundingBox;

  this_boundingBox.lon_min = lon_min;
  this_boundingBox.lon_max = lon_max;
  this_boundingBox.lat_min = lat_min;
  this_boundingBox.lat_max = lat_max;

  m_boundingBoxes[id] = this_boundingBox;

}

void pyToCppModelInterfaceCache::setExtSourceCube(const int id, const boost::numeric::array &cube,
                                                  const boost::numeric::array &lon, const boost::numeric::array &lat)
{

  // Add an extended source to the cache (a map)

  PyArrayObject* cube__ = (PyArrayObject*) cube.ptr();

  unsigned int n_points = (unsigned int) *(cube__->dimensions);
  unsigned int n_energies = (unsigned int) *(cube__->dimensions+1);

  // This is n_points * n_energies in size

  double* cube_ = (double *) cube__->data;

  // These are both n_points in size

  double* lon_ = (double *) ((PyArrayObject*) lon.ptr())->data;
  double* lat_ = (double *) ((PyArrayObject*) lat.ptr())->data;

  ExtSrcCube this_srcCube;

  for(unsigned int i=0; i < n_points; ++i)
  {

    float this_lon = (float) lon_[i];
    float this_lat = (float) lat_[i];

    SkyCoord this_coord(this_lon, this_lat);

    // A little of pointer algebra

    int this_data_start = i * n_energies;
    int this_data_stop = this_data_start + n_energies;

    // Note how this construct avoid the double copy which would
    // occur if we were to first create a vector and then
    // copy it into a standard map. Here instead the operator
    // [] creates an empty vector, which is then filled with
    // the assign method

    this_srcCube[this_coord].assign(cube_ + this_data_start, cube_ + this_data_stop);

  }

  // Finally add to the map

  m_extSources[id] = this_srcCube;

}

bool pyToCppModelInterfaceCache::isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
  return true;
}

int pyToCppModelInterfaceCache::getNumberOfPointSources() const {

  return m_ptsSourcesPos.size();

}

void pyToCppModelInterfaceCache::getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {

  try {

    SkyCoord this_position = m_ptsSourcesPos.at(srcid);
    *j2000_ra = this_position.first;
    *j2000_dec = this_position.second;

  } catch (...) {

    std::stringstream name;

    name << "Point source " << srcid << " not found in position cache";

    throw std::runtime_error(name.str());

  }

}

void pyToCppModelInterfaceCache::reset() {

  //Empty the cache

  m_extSources.clear();
  m_ptsSources.clear();
  /*
  m_boundingBoxes.clear();
  m_nExtSources = 0;
  m_nPtSources = 0;*/

}

std::vector<double>
pyToCppModelInterfaceCache::getPointSourceFluxes(int srcid, std::vector<double> energies) const {

  if (m_ptsSources.count(srcid) == 0)
  {
    // This happens during the construction of LikeHAWC because there is a energy reweighting
    // At that moment the cache is still empty, so let's just return the energy array which
    // has the right size.

    /*
    std::stringstream name;

    name << "Point source " << srcid << " not found in spectrum cache";

    throw std::runtime_error(name.str());*/

    std::cerr << "Point source " << srcid << " not found in spectrum cache" << std::endl;

    return energies;

  } else {

    return m_ptsSources.at(srcid);

  }

}

int pyToCppModelInterfaceCache::getNumberOfExtendedSources() const {

  // We use the size of bounding boxes and not of m_extSources because the latter
  // could get filled in a second moment
  return m_boundingBoxes.size();

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                               std::vector<double> energies) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::vector<double>
pyToCppModelInterfaceCache::getExtendedSourceFluxes_test(int srcid, double j2000_ra, double j2000_dec) const {

  SkyCoord sky_pos(j2000_ra, j2000_dec);

  return m_extSources.at(srcid).at(sky_pos);

}

std::string pyToCppModelInterfaceCache::getPointSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Point source " << srcid;

  return name.str();
}

std::string pyToCppModelInterfaceCache::getExtendedSourceName(int srcid) const {

  //TODO: implement a mechanism to actually keep the true name

  std::stringstream name;

  name << "Extended source " << srcid;

  return name.str();
}

void pyToCppModelInterfaceCache::getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                                        double *j2000_ra_max,
                                                        double *j2000_dec_min,
                                                        double *j2000_dec_max) const {

  const BoundingBox *this_boundingBox = &m_boundingBoxes.at(srcid);

  *j2000_ra_min = this_boundingBox->lon_min;
  *j2000_ra_max = this_boundingBox->lon_max;
  *j2000_dec_min = this_boundingBox->lat_min;
  *j2000_dec_max = this_boundingBox->lat_max;

}

}

using namespace threeML;
using namespace boost::python;

//This is needed to wrap the interface (i.e., all methods are virtual)
//contained in ModelInterface.h
struct ModelInterfaceCacheWrap: ModelInterface, wrapper<ModelInterface> {
  int getNumberOfPointSources() const { return this->get_override("getNumberOfPointSources")(); }

  void getPointSourcePosition(int srcid, double *j2000_ra, double *j2000_dec) const {
    this->get_override("getPointSourcePosition")();
  }

  std::vector<double> getPointSourceFluxes(int srcid, std::vector<double> energies) const {
    return this->get_override("getPointSourceFluxes")();
  }

  std::string getPointSourceName(int srcid) const { return this->get_override("getPointSourceName")(); }

  int getNumberOfExtendedSources() const { return this->get_override("getNumberOfExtendedSources")(); }

  std::vector<double> getExtendedSourceFluxes(int srcid, double j2000_ra, double j2000_dec,
                                              std::vector<double> energies) const {
    return this->get_override("getExtendedSourceFluxes")();
  }

  std::string getExtendedSourceName(int srcid) const { return this->get_override("getExtendedSourceName")(); }

  bool isInsideAnyExtendedSource(double j2000_ra, double j2000_dec) const {
    return this->get_override("isInsideAnyExtendedSource")();
  }

  void getExtendedSourceBoundaries(int srcid, double *j2000_ra_min,
                                   double *j2000_ra_max,
                                   double *j2000_dec_min,
                                   double *j2000_dec_max) const { this->get_override("getExtendedSourceBoundaries")(); }
};

template<class T>
struct VecToList {
  static PyObject *convert(const std::vector<T> &vec) {
    boost::python::list *l = new boost::python::list();

    for (size_t i = 0; i < vec.size(); i++)
      (*l).append(vec[i]);

    return l->ptr();
  }
};

BOOST_PYTHON_MODULE (pyModelInterfaceCache) {
  //hello
  to_python_converter<std::vector<double, std::allocator<double> >, VecToList<double> >();

  class_<ModelInterfaceCacheWrap, boost::noncopyable>("ModelInterface")
      .def("getNumberOfPointSources", pure_virtual(&ModelInterface::getNumberOfPointSources))
      .def("getPointSourcePosition", pure_virtual(&ModelInterface::getPointSourcePosition))
      .def("getPointSourceFluxes", pure_virtual(&ModelInterface::getPointSourceFluxes))
      .def("getPointSourceName", pure_virtual(&ModelInterface::getPointSourceName))
      .def("getNumberOfExtendedSources", pure_virtual(&ModelInterface::getNumberOfExtendedSources))
      .def("getExtendedSourceFluxes", pure_virtual(&ModelInterface::getExtendedSourceFluxes))
      .def("getExtendedSourceName", pure_virtual(&ModelInterface::getExtendedSourceName))
      .def("isInsideAnyExtendedSource", pure_virtual(&ModelInterface::isInsideAnyExtendedSource))
      .def("getExtendedSourceBoundaries", pure_virtual(&ModelInterface::getExtendedSourceBoundaries));

  boost::numeric::array::set_module_and_type("numpy", "ndarray");

  class_<pyToCppModelInterfaceCache, bases<ModelInterface> >("pyToCppModelInterfaceCache", init< >())
      .def("getNumberOfPointSources", &pyToCppModelInterfaceCache::getNumberOfPointSources)
      .def("getPointSourcePosition", &pyToCppModelInterfaceCache::getPointSourcePosition)
      .def("getPointSourceFluxes", &pyToCppModelInterfaceCache::getPointSourceFluxes)
      .def("getPointSourceName", &pyToCppModelInterfaceCache::getPointSourceName)
      .def("getNumberOfExtendedSources", &pyToCppModelInterfaceCache::getNumberOfExtendedSources)
      .def("getExtendedSourceFluxes", &pyToCppModelInterfaceCache::getExtendedSourceFluxes)
      .def("getExtendedSourceName", &pyToCppModelInterfaceCache::getExtendedSourceName)
      .def("isInsideAnyExtendedSource", &pyToCppModelInterfaceCache::isInsideAnyExtendedSource)
      .def("getExtendedSourceBoundaries", &pyToCppModelInterfaceCache::getExtendedSourceBoundaries)
      .def("setExtSourceBoundaries", &pyToCppModelInterfaceCache::setExtSourceBoundaries)
      .def("setExtSourceCube",&pyToCppModelInterfaceCache::setExtSourceCube)
      .def("getExtendedSourceFluxes_test",&pyToCppModelInterfaceCache::getExtendedSourceFluxes_test)
      .def("reset",&pyToCppModelInterfaceCache::reset)
      .def("setPtsSourceSpectrum",&pyToCppModelInterfaceCache::setPtsSourceSpectrum)
      .def("setPtsSourcePosition",&pyToCppModelInterfaceCache::setPtsSourcePosition);
}
<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <cusp/coo_matrix.h>
#include <cusp/array2d.h>

#include <cusp/detail/format_utils.h>

#include <thrust/gather.h>
#include <thrust/scan.h>
#include <thrust/segmented_scan.h>
#include <thrust/scatter.h>
#include <thrust/sort.h>
#include <thrust/transform.h>
#include <thrust/unique.h>

namespace cusp
{
namespace detail
{
namespace generic
{

template <typename IndexType,
          typename ValueType,
          typename SpaceOrAlloc>
void multiply(const cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>& A,
              const cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>& B,
                    cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>& C)
{
    typedef typename cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>::memory_space MemorySpace;

    // check whether matrices are empty
    if (A.num_entries == 0 || B.num_entries == 0)
    {
        cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc> temp(A.num_rows, B.num_cols, 0);
        C.swap(temp);
        return;
    }

    // compute row offsets for B
    cusp::array1d<IndexType,MemorySpace> B_row_offsets(B.num_rows + 1);
    cusp::detail::indices_to_offsets(B.row_indices, B_row_offsets);

    // compute row lengths for B
    cusp::array1d<IndexType,MemorySpace> B_row_lengths(B.num_rows);
    thrust::transform(B_row_offsets.begin() + 1, B_row_offsets.end(), B_row_offsets.begin(), B_row_lengths.begin(), thrust::minus<IndexType>());

    // for each element A(i,j) compute the number of nonzero elements in B(j,:)
    cusp::array1d<IndexType,MemorySpace> segment_lengths(A.num_entries);
    thrust::gather(segment_lengths.begin(), segment_lengths.end(),
                   A.column_indices.begin(),
                   B_row_lengths.begin());

    // output pointer
    cusp::array1d<IndexType,MemorySpace> output_ptr(A.num_entries + 1);
    thrust::exclusive_scan(segment_lengths.begin(), segment_lengths.end(),
                           output_ptr.begin(),
                           IndexType(0));
    output_ptr[A.num_entries] = output_ptr[A.num_entries - 1] + segment_lengths[A.num_entries - 1]; // XXX is this necessary?

    IndexType coo_num_nonzeros = output_ptr[A.num_entries];

    // enumerate the segments in the intermediate format corresponding to each entry A(i,j)
    // XXX could be done with offset_to_index instead
    cusp::array1d<IndexType,MemorySpace> segments(coo_num_nonzeros, 0);
    thrust::scatter_if(thrust::counting_iterator<IndexType>(0), thrust::counting_iterator<IndexType>(A.num_entries),
                       output_ptr.begin(),
                       segment_lengths.begin(),
                       segments.begin());
    thrust::inclusive_scan(segments.begin(), segments.end(), segments.begin(), thrust::maximum<IndexType>());

    // compute gather locations of intermediate format
    cusp::array1d<IndexType,MemorySpace> gather_locations(coo_num_nonzeros, 1);
    {
        // TODO replace temp arrays with permutation_iterator
        // TODO fuse two calls to scatter_if with zip_iterator
        cusp::array1d<IndexType,MemorySpace> temp(A.num_entries);  // B_row_offsets[Aj[n]]

        thrust::gather(temp.begin(), temp.end(),
                       A.column_indices.begin(),
                       B_row_offsets.begin());

        thrust::scatter_if(temp.begin(), temp.end(),
                           output_ptr.begin(),
                           segment_lengths.begin(),
                           gather_locations.begin());
    }
    thrust::experimental::inclusive_segmented_scan(gather_locations.begin(), gather_locations.end(),
                                                   segments.begin(),
                                                   gather_locations.begin());

    // compute column entries and values of intermediate format
    cusp::array1d<IndexType,MemorySpace> I(coo_num_nonzeros);
    cusp::array1d<IndexType,MemorySpace> J(coo_num_nonzeros);
    cusp::array1d<ValueType,MemorySpace> V(coo_num_nonzeros);

    thrust::gather(I.begin(), I.end(),
                   segments.begin(),
                   A.row_indices.begin());

    thrust::gather(J.begin(), J.end(),
                   gather_locations.begin(),
                   B.column_indices.begin());
    {
        // TODO replace temp arrays with permutation_iterator
        cusp::array1d<ValueType,MemorySpace> temp1(coo_num_nonzeros);  // A_values[segments[n]]
        cusp::array1d<ValueType,MemorySpace> temp2(coo_num_nonzeros);  // B_values[gather_locations[n]]

        thrust::gather(temp1.begin(), temp1.end(), segments.begin(),         A.values.begin());
        thrust::gather(temp2.begin(), temp2.end(), gather_locations.begin(), B.values.begin());

        thrust::transform(temp1.begin(), temp1.end(),
                          temp2.begin(),
                          V.begin(),
                          thrust::multiplies<ValueType>());
    }

    // sort by (I,J)
    {
        // TODO use explicit permuation array
        thrust::sort_by_key(J.begin(), J.end(), thrust::make_zip_iterator(thrust::make_tuple(I.begin(), V.begin())));
        thrust::sort_by_key(I.begin(), I.end(), thrust::make_zip_iterator(thrust::make_tuple(J.begin(), V.begin())));
    }

    // compress duplicate (I,J) entries
    size_t NNZ = thrust::unique_by_key(thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())),
                                       thrust::make_zip_iterator(thrust::make_tuple(I.end(), J.end())),
                                       V.begin(),
                                       thrust::equal_to< thrust::tuple<IndexType,IndexType> >(),
                                       thrust::plus<ValueType>()).second - V.begin();
    I.resize(NNZ);
    J.resize(NNZ);
    V.resize(NNZ);

    C.resize(A.num_rows, B.num_cols, NNZ);
    C.row_indices    = I;
    C.column_indices = J;
    C.values         = V;
}

template <typename ValueType,
          typename SpaceOrAlloc>
void multiply(const cusp::array2d<ValueType,SpaceOrAlloc>& A,
              const cusp::array2d<ValueType,SpaceOrAlloc>& B,
                    cusp::array2d<ValueType,SpaceOrAlloc>& C)
{
    C.resize(A.num_rows, B.num_cols);

    for(size_t i = 0; i < C.num_rows; i++)
    {
        for(size_t j = 0; j < C.num_cols; j++)
        {
            ValueType v = 0;

            for(size_t k = 0; k < A.num_cols; k++)
                v += A(i,k) * B(k,j);

            C(i,j) = v;
        }
    }
}

} // end namespace generic
} // end namespace detail
} // end namespace cusp

<commit_msg>used permutation_iterator in sparse matrix-matrix multiply implementation<commit_after>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <cusp/coo_matrix.h>
#include <cusp/array2d.h>

#include <cusp/detail/format_utils.h>

#include <thrust/gather.h>
#include <thrust/scan.h>
#include <thrust/segmented_scan.h>
#include <thrust/scatter.h>
#include <thrust/sort.h>
#include <thrust/transform.h>
#include <thrust/unique.h>
#include <thrust/iterator/permutation_iterator.h>

namespace cusp
{
namespace detail
{
namespace generic
{

template <typename IndexType,
          typename ValueType,
          typename SpaceOrAlloc>
void multiply(const cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>& A,
              const cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>& B,
                    cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>& C)
{
    typedef typename cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc>::memory_space MemorySpace;

    // check whether matrices are empty
    if (A.num_entries == 0 || B.num_entries == 0)
    {
        cusp::coo_matrix<IndexType,ValueType,SpaceOrAlloc> temp(A.num_rows, B.num_cols, 0);
        C.swap(temp);
        return;
    }

    // compute row offsets for B
    cusp::array1d<IndexType,MemorySpace> B_row_offsets(B.num_rows + 1);
    cusp::detail::indices_to_offsets(B.row_indices, B_row_offsets);

    // compute row lengths for B
    cusp::array1d<IndexType,MemorySpace> B_row_lengths(B.num_rows);
    thrust::transform(B_row_offsets.begin() + 1, B_row_offsets.end(), B_row_offsets.begin(), B_row_lengths.begin(), thrust::minus<IndexType>());

    // for each element A(i,j) compute the number of nonzero elements in B(j,:)
    cusp::array1d<IndexType,MemorySpace> segment_lengths(A.num_entries);
    thrust::gather(segment_lengths.begin(), segment_lengths.end(),
                   A.column_indices.begin(),
                   B_row_lengths.begin());

    // output pointer
    cusp::array1d<IndexType,MemorySpace> output_ptr(A.num_entries + 1);
    thrust::exclusive_scan(segment_lengths.begin(), segment_lengths.end(),
                           output_ptr.begin(),
                           IndexType(0));
    output_ptr[A.num_entries] = output_ptr[A.num_entries - 1] + segment_lengths[A.num_entries - 1]; // XXX is this necessary?

    IndexType coo_num_nonzeros = output_ptr[A.num_entries];

    // enumerate the segments in the intermediate format corresponding to each entry A(i,j)
    // XXX could be done with offset_to_index instead
    cusp::array1d<IndexType,MemorySpace> segments(coo_num_nonzeros, 0);
    thrust::scatter_if(thrust::counting_iterator<IndexType>(0), thrust::counting_iterator<IndexType>(A.num_entries),
                       output_ptr.begin(),
                       segment_lengths.begin(),
                       segments.begin());
    thrust::inclusive_scan(segments.begin(), segments.end(), segments.begin(), thrust::maximum<IndexType>());

    // compute gather locations of intermediate format
    cusp::array1d<IndexType,MemorySpace> gather_locations(coo_num_nonzeros, 1);
    thrust::scatter_if(thrust::make_permutation_iterator(B_row_offsets.begin(), A.column_indices.begin()),
                       thrust::make_permutation_iterator(B_row_offsets.begin(), A.column_indices.begin()) + A.num_entries,
                       output_ptr.begin(),
                       segment_lengths.begin(),
                       gather_locations.begin());
    thrust::experimental::inclusive_segmented_scan(gather_locations.begin(), gather_locations.end(),
                                                   segments.begin(),
                                                   gather_locations.begin());

    // compute column entries and values of intermediate format
    cusp::array1d<IndexType,MemorySpace> I(coo_num_nonzeros);
    cusp::array1d<IndexType,MemorySpace> J(coo_num_nonzeros);
    cusp::array1d<ValueType,MemorySpace> V(coo_num_nonzeros);

    thrust::gather(I.begin(), I.end(),
                   segments.begin(),
                   A.row_indices.begin());

    thrust::gather(J.begin(), J.end(),
                   gather_locations.begin(),
                   B.column_indices.begin());

    thrust::transform(thrust::make_permutation_iterator(A.values.begin(), segments.begin()),
                      thrust::make_permutation_iterator(A.values.begin(), segments.begin()) + coo_num_nonzeros,
                      thrust::make_permutation_iterator(B.values.begin(), gather_locations.begin()),
                      V.begin(),
                      thrust::multiplies<ValueType>());

    // sort by (I,J)
    {
        // TODO use explicit permuation and temporary arrays for efficiency
        thrust::sort_by_key(J.begin(), J.end(), thrust::make_zip_iterator(thrust::make_tuple(I.begin(), V.begin())));
        thrust::sort_by_key(I.begin(), I.end(), thrust::make_zip_iterator(thrust::make_tuple(J.begin(), V.begin())));
    }

    // compress duplicate (I,J) entries
    size_t NNZ = thrust::unique_by_key(thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())),
                                       thrust::make_zip_iterator(thrust::make_tuple(I.end(), J.end())),
                                       V.begin(),
                                       thrust::equal_to< thrust::tuple<IndexType,IndexType> >(),
                                       thrust::plus<ValueType>()).second - V.begin();
    I.resize(NNZ);
    J.resize(NNZ);
    V.resize(NNZ);

    C.resize(A.num_rows, B.num_cols, NNZ);
    C.row_indices    = I;
    C.column_indices = J;
    C.values         = V;
}

template <typename ValueType,
          typename SpaceOrAlloc>
void multiply(const cusp::array2d<ValueType,SpaceOrAlloc>& A,
              const cusp::array2d<ValueType,SpaceOrAlloc>& B,
                    cusp::array2d<ValueType,SpaceOrAlloc>& C)
{
    C.resize(A.num_rows, B.num_cols);

    for(size_t i = 0; i < C.num_rows; i++)
    {
        for(size_t j = 0; j < C.num_cols; j++)
        {
            ValueType v = 0;

            for(size_t k = 0; k < A.num_cols; k++)
                v += A(i,k) * B(k,j);

            C(i,j) = v;
        }
    }
}

} // end namespace generic
} // end namespace detail
} // end namespace cusp

<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <cusp/coo_matrix.h>
#include <cusp/array2d.h>

#include <cusp/detail/format_utils.h>

#include <thrust/gather.h>
#include <thrust/scan.h>
#include <thrust/segmented_scan.h>
#include <thrust/scatter.h>
#include <thrust/sort.h>
#include <thrust/transform.h>
#include <thrust/reduce.h>
#include <thrust/iterator/permutation_iterator.h>

namespace cusp
{
namespace detail
{
namespace generic
{

template <typename IndexType,
          typename ValueType,
          typename MemorySpace>
void multiply(const cusp::coo_matrix<IndexType,ValueType,MemorySpace>& A,
              const cusp::coo_matrix<IndexType,ValueType,MemorySpace>& B,
                    cusp::coo_matrix<IndexType,ValueType,MemorySpace>& C)
{
    // check whether matrices are empty
    if (A.num_entries == 0 || B.num_entries == 0)
    {
        cusp::coo_matrix<IndexType,ValueType,MemorySpace> temp(A.num_rows, B.num_cols, 0);
        C.swap(temp);
        return;
    }

    // compute row offsets for B
    cusp::array1d<IndexType,MemorySpace> B_row_offsets(B.num_rows + 1);
    cusp::detail::indices_to_offsets(B.row_indices, B_row_offsets);

    // compute row lengths for B
    cusp::array1d<IndexType,MemorySpace> B_row_lengths(B.num_rows);
    thrust::transform(B_row_offsets.begin() + 1, B_row_offsets.end(), B_row_offsets.begin(), B_row_lengths.begin(), thrust::minus<IndexType>());

    // for each element A(i,j) compute the number of nonzero elements in B(j,:)
    cusp::array1d<IndexType,MemorySpace> segment_lengths(A.num_entries);
    // XXX REMOVE
    //thrust::gather(segment_lengths.begin(), segment_lengths.end(),
    //               A.column_indices.begin(),
    //               B_row_lengths.begin());
    thrust::next::gather(A.column_indices.begin(), A.column_indices.end(),
                   B_row_lengths.begin(),
                   segment_lengths.begin());

    // output pointer
    cusp::array1d<IndexType,MemorySpace> output_ptr(A.num_entries + 1);
    thrust::exclusive_scan(segment_lengths.begin(), segment_lengths.end(),
                           output_ptr.begin(),
                           IndexType(0));
    output_ptr[A.num_entries] = output_ptr[A.num_entries - 1] + segment_lengths[A.num_entries - 1]; // XXX is this necessary?

    IndexType coo_num_nonzeros = output_ptr[A.num_entries];

    // enumerate the segments in the intermediate format corresponding to each entry A(i,j)
    // XXX could be done with offset_to_index instead
    cusp::array1d<IndexType,MemorySpace> segments(coo_num_nonzeros, 0);
    thrust::scatter_if(thrust::counting_iterator<IndexType>(0), thrust::counting_iterator<IndexType>(A.num_entries),
                       output_ptr.begin(),
                       segment_lengths.begin(),
                       segments.begin());
    thrust::inclusive_scan(segments.begin(), segments.end(), segments.begin(), thrust::maximum<IndexType>());

    // compute gather locations of intermediate format
    cusp::array1d<IndexType,MemorySpace> gather_locations(coo_num_nonzeros, 1);
    thrust::scatter_if(thrust::make_permutation_iterator(B_row_offsets.begin(), A.column_indices.begin()),
                       thrust::make_permutation_iterator(B_row_offsets.begin(), A.column_indices.begin()) + A.num_entries,
                       output_ptr.begin(),
                       segment_lengths.begin(),
                       gather_locations.begin());
    thrust::experimental::inclusive_segmented_scan(gather_locations.begin(), gather_locations.end(),
                                                   segments.begin(),
                                                   gather_locations.begin());

    // compute column entries and values of intermediate format
    cusp::array1d<IndexType,MemorySpace> I(coo_num_nonzeros);
    cusp::array1d<IndexType,MemorySpace> J(coo_num_nonzeros);
    cusp::array1d<ValueType,MemorySpace> V(coo_num_nonzeros);

    thrust::next::gather(segments.begin(), segments.end(),
                         A.row_indices.begin(),
                         I.begin());

    thrust::next::gather(gather_locations.begin(), gather_locations.end(),
                         B.column_indices.begin(),
                         J.begin());

    thrust::transform(thrust::make_permutation_iterator(A.values.begin(), segments.begin()),
                      thrust::make_permutation_iterator(A.values.begin(), segments.begin()) + coo_num_nonzeros,
                      thrust::make_permutation_iterator(B.values.begin(), gather_locations.begin()),
                      V.begin(),
                      thrust::multiplies<ValueType>());

    // sort by (I,J)
    {
        // TODO use explicit permuation and temporary arrays for efficiency
        thrust::sort_by_key(J.begin(), J.end(), thrust::make_zip_iterator(thrust::make_tuple(I.begin(), V.begin())));
        thrust::sort_by_key(I.begin(), I.end(), thrust::make_zip_iterator(thrust::make_tuple(J.begin(), V.begin())));
    }

    // compute unique number of nonzeros in the output
    IndexType NNZ = thrust::inner_product(thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())),
                                          thrust::make_zip_iterator(thrust::make_tuple(I.end (), J.end()))    - 1,
                                          thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())) + 1,
                                          IndexType(0),
                                          thrust::plus<IndexType>(),
                                          thrust::not_equal_to< thrust::tuple<IndexType,IndexType> >()) + 1;

    // allocate space for output
    C.resize(A.num_rows, B.num_cols, NNZ);

    // sum values with the same (i,j)
    thrust::reduce_by_key(thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())),
                          thrust::make_zip_iterator(thrust::make_tuple(I.end(),   J.end())),
                          V.begin(),
                          thrust::make_zip_iterator(thrust::make_tuple(C.row_indices.begin(), C.column_indices.begin())),
                          C.values.begin(),
                          thrust::equal_to< thrust::tuple<IndexType,IndexType> >(),
                          thrust::plus<ValueType>());
}

template <typename ValueType,
          typename MemorySpace>
void multiply(const cusp::array2d<ValueType,MemorySpace>& A,
              const cusp::array2d<ValueType,MemorySpace>& B,
                    cusp::array2d<ValueType,MemorySpace>& C)
{
    C.resize(A.num_rows, B.num_cols);

    for(size_t i = 0; i < C.num_rows; i++)
    {
        for(size_t j = 0; j < C.num_cols; j++)
        {
            ValueType v = 0;

            for(size_t k = 0; k < A.num_cols; k++)
                v += A(i,k) * B(k,j);

            C(i,j) = v;
        }
    }
}

} // end namespace generic
} // end namespace detail
} // end namespace cusp

<commit_msg>removed old code<commit_after>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <cusp/coo_matrix.h>
#include <cusp/array2d.h>

#include <cusp/detail/format_utils.h>

#include <thrust/gather.h>
#include <thrust/scan.h>
#include <thrust/segmented_scan.h>
#include <thrust/scatter.h>
#include <thrust/sort.h>
#include <thrust/transform.h>
#include <thrust/reduce.h>
#include <thrust/iterator/permutation_iterator.h>

namespace cusp
{
namespace detail
{
namespace generic
{

template <typename IndexType,
          typename ValueType,
          typename MemorySpace>
void multiply(const cusp::coo_matrix<IndexType,ValueType,MemorySpace>& A,
              const cusp::coo_matrix<IndexType,ValueType,MemorySpace>& B,
                    cusp::coo_matrix<IndexType,ValueType,MemorySpace>& C)
{
    // check whether matrices are empty
    if (A.num_entries == 0 || B.num_entries == 0)
    {
        cusp::coo_matrix<IndexType,ValueType,MemorySpace> temp(A.num_rows, B.num_cols, 0);
        C.swap(temp);
        return;
    }

    // compute row offsets for B
    cusp::array1d<IndexType,MemorySpace> B_row_offsets(B.num_rows + 1);
    cusp::detail::indices_to_offsets(B.row_indices, B_row_offsets);

    // compute row lengths for B
    cusp::array1d<IndexType,MemorySpace> B_row_lengths(B.num_rows);
    thrust::transform(B_row_offsets.begin() + 1, B_row_offsets.end(), B_row_offsets.begin(), B_row_lengths.begin(), thrust::minus<IndexType>());

    // for each element A(i,j) compute the number of nonzero elements in B(j,:)
    cusp::array1d<IndexType,MemorySpace> segment_lengths(A.num_entries);
    thrust::next::gather(A.column_indices.begin(), A.column_indices.end(),
                   B_row_lengths.begin(),
                   segment_lengths.begin());

    // output pointer
    cusp::array1d<IndexType,MemorySpace> output_ptr(A.num_entries + 1);
    thrust::exclusive_scan(segment_lengths.begin(), segment_lengths.end(),
                           output_ptr.begin(),
                           IndexType(0));
    output_ptr[A.num_entries] = output_ptr[A.num_entries - 1] + segment_lengths[A.num_entries - 1]; // XXX is this necessary?

    IndexType coo_num_nonzeros = output_ptr[A.num_entries];

    // enumerate the segments in the intermediate format corresponding to each entry A(i,j)
    // XXX could be done with offset_to_index instead
    cusp::array1d<IndexType,MemorySpace> segments(coo_num_nonzeros, 0);
    thrust::scatter_if(thrust::counting_iterator<IndexType>(0), thrust::counting_iterator<IndexType>(A.num_entries),
                       output_ptr.begin(),
                       segment_lengths.begin(),
                       segments.begin());
    thrust::inclusive_scan(segments.begin(), segments.end(), segments.begin(), thrust::maximum<IndexType>());

    // compute gather locations of intermediate format
    cusp::array1d<IndexType,MemorySpace> gather_locations(coo_num_nonzeros, 1);
    thrust::scatter_if(thrust::make_permutation_iterator(B_row_offsets.begin(), A.column_indices.begin()),
                       thrust::make_permutation_iterator(B_row_offsets.begin(), A.column_indices.begin()) + A.num_entries,
                       output_ptr.begin(),
                       segment_lengths.begin(),
                       gather_locations.begin());
    thrust::experimental::inclusive_segmented_scan(gather_locations.begin(), gather_locations.end(),
                                                   segments.begin(),
                                                   gather_locations.begin());

    // compute column entries and values of intermediate format
    cusp::array1d<IndexType,MemorySpace> I(coo_num_nonzeros);
    cusp::array1d<IndexType,MemorySpace> J(coo_num_nonzeros);
    cusp::array1d<ValueType,MemorySpace> V(coo_num_nonzeros);

    thrust::next::gather(segments.begin(), segments.end(),
                         A.row_indices.begin(),
                         I.begin());

    thrust::next::gather(gather_locations.begin(), gather_locations.end(),
                         B.column_indices.begin(),
                         J.begin());

    thrust::transform(thrust::make_permutation_iterator(A.values.begin(), segments.begin()),
                      thrust::make_permutation_iterator(A.values.begin(), segments.begin()) + coo_num_nonzeros,
                      thrust::make_permutation_iterator(B.values.begin(), gather_locations.begin()),
                      V.begin(),
                      thrust::multiplies<ValueType>());

    // sort by (I,J)
    {
        // TODO use explicit permuation and temporary arrays for efficiency
        thrust::sort_by_key(J.begin(), J.end(), thrust::make_zip_iterator(thrust::make_tuple(I.begin(), V.begin())));
        thrust::sort_by_key(I.begin(), I.end(), thrust::make_zip_iterator(thrust::make_tuple(J.begin(), V.begin())));
    }

    // compute unique number of nonzeros in the output
    IndexType NNZ = thrust::inner_product(thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())),
                                          thrust::make_zip_iterator(thrust::make_tuple(I.end (), J.end()))    - 1,
                                          thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())) + 1,
                                          IndexType(0),
                                          thrust::plus<IndexType>(),
                                          thrust::not_equal_to< thrust::tuple<IndexType,IndexType> >()) + 1;

    // allocate space for output
    C.resize(A.num_rows, B.num_cols, NNZ);

    // sum values with the same (i,j)
    thrust::reduce_by_key(thrust::make_zip_iterator(thrust::make_tuple(I.begin(), J.begin())),
                          thrust::make_zip_iterator(thrust::make_tuple(I.end(),   J.end())),
                          V.begin(),
                          thrust::make_zip_iterator(thrust::make_tuple(C.row_indices.begin(), C.column_indices.begin())),
                          C.values.begin(),
                          thrust::equal_to< thrust::tuple<IndexType,IndexType> >(),
                          thrust::plus<ValueType>());
}

template <typename ValueType,
          typename MemorySpace>
void multiply(const cusp::array2d<ValueType,MemorySpace>& A,
              const cusp::array2d<ValueType,MemorySpace>& B,
                    cusp::array2d<ValueType,MemorySpace>& C)
{
    C.resize(A.num_rows, B.num_cols);

    for(size_t i = 0; i < C.num_rows; i++)
    {
        for(size_t j = 0; j < C.num_cols; j++)
        {
            ValueType v = 0;

            for(size_t k = 0; k < A.num_cols; k++)
                v += A(i,k) * B(k,j);

            C(i,j) = v;
        }
    }
}

} // end namespace generic
} // end namespace detail
} // end namespace cusp

<|endoftext|>