<commit_before>/*************************************************************************
 *
 *  $RCSfile: fulinend.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2004-02-03 20:16:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include "fulinend.hxx"

#ifndef _XTABLE_HXX
#include <svx/xtable.hxx>
#endif
//CHINA001 #ifndef _SVX_DLG_NAME_HXX //autogen
//CHINA001 #include <svx/dlgname.hxx>
//CHINA001 #endif
#include <svx/svxdlg.hxx> //CHINA001
#include <svx/dialogs.hrc> //CHINA001
#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef _SVDOPATH_HXX //autogen
#include <svx/svdopath.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif

#include "strings.hrc"
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#include "helpids.h"
#include "sdresid.hxx"
#include "drawdoc.hxx"
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_WINDOW_SHELL_HXX
#include "Window.hxx"
#endif

namespace sd {

#define BITMAP_WIDTH  32
#define BITMAP_HEIGHT 12

TYPEINIT1( FuLineEnd, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuLineEnd::FuLineEnd(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
                    SdDrawDocument* pDoc, SfxRequest& rReq)
    : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
{
    const SdrMarkList& rMarkList = pView->GetMarkList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        const SdrObject* pObj = rMarkList.GetMark(0)->GetObj();
        const SdrObject* pNewObj;
        SdrObject* pConvPolyObj = NULL;

        if( pObj->ISA( SdrPathObj ) )
        {
            pNewObj = pObj;
        }
        else
        {
            SdrObjTransformInfoRec aInfoRec;
            pObj->TakeObjInfo( aInfoRec );

            if( aInfoRec.bCanConvToPath &&
                pObj->GetObjInventor() == SdrInventor &&
                pObj->GetObjIdentifier() != OBJ_GRUP )
                // bCanConvToPath ist bei Gruppenobjekten TRUE,
                // stuerzt aber bei ConvertToPathObj() ab !
            {
                pNewObj = pConvPolyObj = pObj->ConvertToPolyObj( TRUE, FALSE );

                if( !pNewObj || !pNewObj->ISA( SdrPathObj ) )
                    return; // Abbruch, zusaetzliche Sicherheit, die bei
                            // Gruppenobjekten aber nichts bringt.
            }
            else return; // Abbruch
        }

        const XPolygon aXPoly = ( (SdrPathObj*) pNewObj )->GetPathPoly().GetObject( 0 );

        // Loeschen des angelegten PolyObjektes
        if( pConvPolyObj )
            delete pConvPolyObj;

        XLineEndList* pLineEndList = pDoc->GetLineEndList();
        XLineEndEntry* pEntry;

        String aNewName( SdResId( STR_LINEEND ) );
        String aDesc( SdResId( STR_DESC_LINEEND ) );
        String aName;

        long nCount = pLineEndList->Count();
        long j = 1;
        BOOL bDifferent = FALSE;

        while( !bDifferent )
        {
            aName = aNewName;
            aName.Append( sal_Unicode(' ') );
            aName.Append( UniString::CreateFromInt32( j++ ) );
            bDifferent = TRUE;
            for( long i = 0; i < nCount && bDifferent; i++ )
            {
                if( aName == pLineEndList->Get( i )->GetName() )
                    bDifferent = FALSE;
            }
        }

        //CHINA001 SvxNameDialog* pDlg = new SvxNameDialog( NULL, aName, aDesc );
        SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
        DBG_ASSERT(pFact, "Dialogdiet fail!");//CHINA001
        AbstractSvxNameDialog* pDlg = pFact->CreateSvxNameDialog( NULL, aName, aDesc, ResId(RID_SVXDLG_NAME) );
        DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
        pDlg->SetEditHelpId( HID_SD_NAMEDIALOG_LINEEND );

        if( pDlg->Execute() == RET_OK )
        {
            pDlg->GetName( aName );
            bDifferent = TRUE;

            for( long i = 0; i < nCount && bDifferent; i++ )
            {
                if( aName == pLineEndList->Get( i )->GetName() )
                    bDifferent = FALSE;
            }

            if( bDifferent )
            {
            /*
                XOutdevItemPool* pItemPool = (XOutdevItemPool*) &pViewSh->GetPool();
                XLineAttrSetItem aXLSet( pItemPool );
                XFillAttrSetItem aXFSet( pItemPool );
                VirtualDevice    aTmpVD ( *pWindow );
                XOutputDevice    aTmpXOut( &aTmpVD, pItemPool );

                aTmpVD.ChangeMapMode( MAP_100TH_MM );
                aTmpVD.SetOutputSize( aTmpVD.PixelToLogic( Size( BITMAP_WIDTH * 2, BITMAP_HEIGHT ) ) );
                aXLSet.GetItemSet().Put( XLineStartWidthItem( aTmpVD.GetOutputSize().Height() ) );
                aXLSet.GetItemSet().Put( XLineEndWidthItem( aTmpVD.GetOutputSize().Height() ) );
                aXFSet.GetItemSet().Put( XFillColorItem( String(), Color( COL_WHITE ) ) );
                aXFSet.GetItemSet().Put( XFillStyleItem( XFILL_SOLID ) );
                aXLSet.GetItemSet().Put( XLineStyleItem( XLINE_NONE ) );

                aTmpXOut.SetLineAttr( ( const XLineAttrSetItem& ) pItemPool->Put( aXLSet ) );
                aTmpXOut.SetFillAttr( ( const XFillAttrSetItem& ) pItemPool->Put( aXFSet ) );
                aTmpXOut.DrawRect( Rectangle( Point(), aTmpVD.GetOutputSize() ) );

                aXLSet.GetItemSet().Put( XLineStyleItem( XLINE_SOLID ) );
                aXLSet.GetItemSet().Put( XLineStartItem( String(), aXPoly ) );
                aXLSet.GetItemSet().Put( XLineEndItem( String(), aXPoly ) );

                aTmpXOut.SetLineAttr( ( const XLineAttrSetItem& ) pItemPool->Put( aXLSet ) );
                aTmpXOut.DrawLine( Point( 0, aTmpVD.GetOutputSize().Height() / 2 ),
                                    Point( aTmpVD.GetOutputSize().Width(), aTmpVD.GetOutputSize().Height() / 2 ) );
                Bitmap* pBitmap = new Bitmap( aTmpVD.GetBitmap( Point(), aTmpVD.GetOutputSize() ) );
            */
                pEntry = new XLineEndEntry( aXPoly, aName );
                pLineEndList->Insert( pEntry, LIST_APPEND);
            }
            else
            {
                String aStr(SdResId( STR_WARN_NAME_DUPLICATE ));
                WarningBox aWarningBox( pWin, WinBits( WB_OK ),
                     aStr );
                aWarningBox.Execute();
            }
        }
        delete pDlg;
    }
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS aw013 (1.4.120); FILE MERGED 2004/06/24 09:33:11 aw 1.4.120.1: #i29181#<commit_after>/*************************************************************************
 *
 *  $RCSfile: fulinend.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-12 15:03:37 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include "fulinend.hxx"

#ifndef _XTABLE_HXX
#include <svx/xtable.hxx>
#endif
//CHINA001 #ifndef _SVX_DLG_NAME_HXX //autogen
//CHINA001 #include <svx/dlgname.hxx>
//CHINA001 #endif
#include <svx/svxdlg.hxx> //CHINA001
#include <svx/dialogs.hrc> //CHINA001
#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef _SVDOPATH_HXX //autogen
#include <svx/svdopath.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif

#include "strings.hrc"
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#include "helpids.h"
#include "sdresid.hxx"
#include "drawdoc.hxx"
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_WINDOW_SHELL_HXX
#include "Window.hxx"
#endif

namespace sd {

#define BITMAP_WIDTH  32
#define BITMAP_HEIGHT 12

TYPEINIT1( FuLineEnd, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuLineEnd::FuLineEnd(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
                    SdDrawDocument* pDoc, SfxRequest& rReq)
    : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
{
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        const SdrObject* pObj = rMarkList.GetMark(0)->GetObj();
        const SdrObject* pNewObj;
        SdrObject* pConvPolyObj = NULL;

        if( pObj->ISA( SdrPathObj ) )
        {
            pNewObj = pObj;
        }
        else
        {
            SdrObjTransformInfoRec aInfoRec;
            pObj->TakeObjInfo( aInfoRec );

            if( aInfoRec.bCanConvToPath &&
                pObj->GetObjInventor() == SdrInventor &&
                pObj->GetObjIdentifier() != OBJ_GRUP )
                // bCanConvToPath ist bei Gruppenobjekten TRUE,
                // stuerzt aber bei ConvertToPathObj() ab !
            {
                pNewObj = pConvPolyObj = pObj->ConvertToPolyObj( TRUE, FALSE );

                if( !pNewObj || !pNewObj->ISA( SdrPathObj ) )
                    return; // Abbruch, zusaetzliche Sicherheit, die bei
                            // Gruppenobjekten aber nichts bringt.
            }
            else return; // Abbruch
        }

        const XPolygon aXPoly = ( (SdrPathObj*) pNewObj )->GetPathPoly().GetObject( 0 );

        // Loeschen des angelegten PolyObjektes
        if( pConvPolyObj )
            delete pConvPolyObj;

        XLineEndList* pLineEndList = pDoc->GetLineEndList();
        XLineEndEntry* pEntry;

        String aNewName( SdResId( STR_LINEEND ) );
        String aDesc( SdResId( STR_DESC_LINEEND ) );
        String aName;

        long nCount = pLineEndList->Count();
        long j = 1;
        BOOL bDifferent = FALSE;

        while( !bDifferent )
        {
            aName = aNewName;
            aName.Append( sal_Unicode(' ') );
            aName.Append( UniString::CreateFromInt32( j++ ) );
            bDifferent = TRUE;
            for( long i = 0; i < nCount && bDifferent; i++ )
            {
                if( aName == pLineEndList->Get( i )->GetName() )
                    bDifferent = FALSE;
            }
        }

        //CHINA001 SvxNameDialog* pDlg = new SvxNameDialog( NULL, aName, aDesc );
        SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
        DBG_ASSERT(pFact, "Dialogdiet fail!");//CHINA001
        AbstractSvxNameDialog* pDlg = pFact->CreateSvxNameDialog( NULL, aName, aDesc, ResId(RID_SVXDLG_NAME) );
        DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
        pDlg->SetEditHelpId( HID_SD_NAMEDIALOG_LINEEND );

        if( pDlg->Execute() == RET_OK )
        {
            pDlg->GetName( aName );
            bDifferent = TRUE;

            for( long i = 0; i < nCount && bDifferent; i++ )
            {
                if( aName == pLineEndList->Get( i )->GetName() )
                    bDifferent = FALSE;
            }

            if( bDifferent )
            {
            /*
                XOutdevItemPool* pItemPool = (XOutdevItemPool*) &pViewSh->GetPool();
                XLineAttrSetItem aXLSet( pItemPool );
                XFillAttrSetItem aXFSet( pItemPool );
                VirtualDevice    aTmpVD ( *pWindow );
                XOutputDevice    aTmpXOut( &aTmpVD, pItemPool );

                aTmpVD.ChangeMapMode( MAP_100TH_MM );
                aTmpVD.SetOutputSize( aTmpVD.PixelToLogic( Size( BITMAP_WIDTH * 2, BITMAP_HEIGHT ) ) );
                aXLSet.GetItemSet().Put( XLineStartWidthItem( aTmpVD.GetOutputSize().Height() ) );
                aXLSet.GetItemSet().Put( XLineEndWidthItem( aTmpVD.GetOutputSize().Height() ) );
                aXFSet.GetItemSet().Put( XFillColorItem( String(), Color( COL_WHITE ) ) );
                aXFSet.GetItemSet().Put( XFillStyleItem( XFILL_SOLID ) );
                aXLSet.GetItemSet().Put( XLineStyleItem( XLINE_NONE ) );

                aTmpXOut.SetLineAttr( ( const XLineAttrSetItem& ) pItemPool->Put( aXLSet ) );
                aTmpXOut.SetFillAttr( ( const XFillAttrSetItem& ) pItemPool->Put( aXFSet ) );
                aTmpXOut.DrawRect( Rectangle( Point(), aTmpVD.GetOutputSize() ) );

                aXLSet.GetItemSet().Put( XLineStyleItem( XLINE_SOLID ) );
                aXLSet.GetItemSet().Put( XLineStartItem( String(), aXPoly ) );
                aXLSet.GetItemSet().Put( XLineEndItem( String(), aXPoly ) );

                aTmpXOut.SetLineAttr( ( const XLineAttrSetItem& ) pItemPool->Put( aXLSet ) );
                aTmpXOut.DrawLine( Point( 0, aTmpVD.GetOutputSize().Height() / 2 ),
                                    Point( aTmpVD.GetOutputSize().Width(), aTmpVD.GetOutputSize().Height() / 2 ) );
                Bitmap* pBitmap = new Bitmap( aTmpVD.GetBitmap( Point(), aTmpVD.GetOutputSize() ) );
            */
                pEntry = new XLineEndEntry( aXPoly, aName );
                pLineEndList->Insert( pEntry, LIST_APPEND);
            }
            else
            {
                String aStr(SdResId( STR_WARN_NAME_DUPLICATE ));
                WarningBox aWarningBox( pWin, WinBits( WB_OK ),
                     aStr );
                aWarningBox.Execute();
            }
        }
        delete pDlg;
    }
}

} // end of namespace sd
<|endoftext|>


<commit_before>#include <catch.hpp>

#include <boost/filesystem.hpp>

#include "../ris_lib/ris_json_resources.h"
#include "../ris_lib/ris_resource_loader.h"
#include "../ris_lib/ris_resources.h"

class fixture {
protected:
    boost::filesystem::path test_data;
public:
    fixture() {
        static const char* candiadates[] = {
            ".",
            "./acceptance_test",
            "../acceptance_test",
        };
        for (auto p : candiadates) {
            if (exists(boost::filesystem::path(p) / "test.bin")) {
                test_data = p;
                break;
            }
        }
        REQUIRE(exists(test_data / "test.bin"));
        REQUIRE(exists(test_data / "test.json"));
    }
};

TEST_CASE_METHOD(fixture,"loading the resource") {
    auto r = ris::json_resources((test_data / "test.json").generic_string());
    CHECK(r.resources().resources.size() > 0);
}<commit_msg>resource fidelity ok<commit_after>#include <catch.hpp>

#include "resource.h"

#include <boost/filesystem.hpp>

#include "../ris_lib/ris_json_resources.h"
#include "../ris_lib/ris_resource_loader.h"
#include "../ris_lib/ris_resources.h"

class fixture {
protected:
    boost::filesystem::path test_data;
public:
    fixture() {
        static const char* candiadates[] = {
            ".",
            "./acceptance_test",
            "../acceptance_test",
        };
        for (auto p : candiadates) {
            if (exists(boost::filesystem::path(p) / "test.bin")) {
                test_data = p;
                break;
            }
        }
        REQUIRE(exists(test_data / "test.bin"));
        REQUIRE(exists(test_data / "test.json"));
    }
};

TEST_CASE_METHOD(fixture,"loading the resource") {
    auto r = ris::json_resources((test_data / "test.json").generic_string());

    auto& resources = r.resources().resources;

    REQUIRE(resources.size() > 0);

    std::vector<std::string> keys;
    test::Resource::GetKeys([&keys](const char* key){
        keys.emplace_back(key);
    });

    CHECK(resources.size() == keys.size());

    SECTION("resource fidelity") {
        for (auto& res : resources) {
            auto reference_data = ris::resource_loader(res,test_data.generic_string()).get();
            auto resource_data = test::Resource::Get(res.name);
            INFO(res.name);
            CHECK(reference_data == resource_data);
        }
    }
}
<|endoftext|>


<commit_before>#include "intermediate_result.hpp"

#include "../storage/country_info.hpp"

#include "../indexer/classificator.hpp"
#include "../indexer/feature.hpp"
#include "../indexer/feature_utils.hpp"
#include "../indexer/mercator.hpp"

#include "../geometry/angles.hpp"
#include "../geometry/distance_on_sphere.hpp"

#include "../base/string_utils.hpp"
#include "../base/logging.hpp"

namespace search
{
namespace impl
{

IntermediateResult::IntermediateResult(m2::RectD const & viewportRect, m2::PointD const & pos,
                                       FeatureType const & f,
                                       string const & displayName, string const & fileName)
  : m_types(f),
    m_str(displayName),
    m_rect(f.GetLimitRect(-2)),
    m_resultType(RESULT_FEATURE)
{
  ASSERT_GREATER(m_types.Size(), 0, ());

  // get region info
  if (!fileName.empty())
    m_region.SetName(fileName);
  else
  {
    if (f.GetFeatureType() == feature::GEOM_POINT)
      m_region.SetPoint(f.GetCenter());
  }

  CalcCommonParams(viewportRect, pos);
  m_searchRank = feature::GetSearchRank(m_types, m_rect.Center(), f.GetPopulation());
}

IntermediateResult::IntermediateResult(m2::RectD const & viewportRect, m2::PointD const & pos,
                                       double lat, double lon, double precision)
  : m_str("(" + strings::to_string(lat) + ", " + strings::to_string(lon) + ")"),
    m_rect(MercatorBounds::LonToX(lon - precision), MercatorBounds::LatToY(lat - precision),
           MercatorBounds::LonToX(lon + precision), MercatorBounds::LatToY(lat + precision)),
    m_resultType(RESULT_LATLON), m_searchRank(0)
{
  CalcCommonParams(viewportRect, pos);

  // get region info
  m_region.SetPoint(m2::PointD(MercatorBounds::LonToX(lon),
                               MercatorBounds::LatToY(lat)));
}

void IntermediateResult::CalcCommonParams(m2::RectD const & viewportRect, m2::PointD const & pos)
{
  m2::PointD const center = m_rect.Center();

  // Check if point is valid (see Query::empty_pos_value).
  if (pos.x > -500 && pos.y > -500)
  {
    ASSERT ( my::between_s(-180.0, 180.0, pos.x), (pos.x) );
    ASSERT ( my::between_s(-180.0, 180.0, pos.y), (pos.y) );

    m_distance = ResultDistance(pos, center);
  }
  else
    m_distance = -1.0;

  m_viewportDistance = ViewportDistance(viewportRect, center);
}

IntermediateResult::IntermediateResult(string const & name, int penalty)
  : m_str(name), m_completionString(name + " "),
    // Categories should always be first
    m_distance(0), m_viewportDistance(0),
    m_resultType(RESULT_CATEGORY),
    m_searchRank(0)
{
}

/*
bool IntermediateResult::LessOrderF::operator()
          (IntermediateResult const & r1, IntermediateResult const & r2) const
{
  if (r1.m_resultType != r2.m_resultType)
    return (r1.m_resultType < r2.m_resultType);

  if (r1.m_searchRank != r2.m_searchRank)
    return (r1.m_searchRank > r2.m_searchRank);

  return (r1.m_distance < r2.m_distance);
}
*/

bool IntermediateResult::LessRank(IntermediateResult const & r1, IntermediateResult const & r2)
{
  return (r1.m_searchRank > r2.m_searchRank);
}

bool IntermediateResult::LessDistance(IntermediateResult const & r1, IntermediateResult const & r2)
{
  return (r1.m_distance < r2.m_distance);

  /*
  if (r1.m_distance != r2.m_distance)
    return (r1.m_distance < r2.m_distance);
  else
    return LessRank(r1, r2);
  */
}

bool IntermediateResult::LessViewportDistance(IntermediateResult const & r1, IntermediateResult const & r2)
{
  return (r1.m_viewportDistance < r2.m_viewportDistance);

  /*
  if (r1.m_viewportDistance != r2.m_viewportDistance)
    return (r1.m_viewportDistance < r2.m_viewportDistance);
  else
    return LessRank(r1, r2);
  */
}

Result IntermediateResult::GenerateFinalResult(
    storage::CountryInfoGetter const * pInfo,
    CategoriesT const * pCat) const
{
  storage::CountryInfo info;
  m_region.GetRegion(pInfo, info);

  switch (m_resultType)
  {
  case RESULT_FEATURE:
    return Result(m_str, info.m_name, info.m_flag, GetFeatureType(pCat)
              #ifdef DEBUG
                  + ' ' + strings::to_string(static_cast<int>(m_searchRank))
              #endif
                  ,
                  GetBestType(), feature::GetFeatureViewport(m_types, m_rect),
                  m_distance);

  case RESULT_LATLON:
    return Result(m_str, info.m_name, info.m_flag, GetFeatureType(pCat),
                  0, m_rect, m_distance);

  default:
    ASSERT_EQUAL ( m_resultType, RESULT_CATEGORY, () );
    return Result(m_str, m_completionString);
  }
}

double IntermediateResult::ResultDistance(m2::PointD const & a, m2::PointD const & b)
{
  return ms::DistanceOnEarth(MercatorBounds::YToLat(a.y), MercatorBounds::XToLon(a.x),
                             MercatorBounds::YToLat(b.y), MercatorBounds::XToLon(b.x));
}

double IntermediateResult::ResultDirection(m2::PointD const & a, m2::PointD const & b)
{
  return ang::AngleTo(a, b);
}

int IntermediateResult::ViewportDistance(m2::RectD const & viewport, m2::PointD const & p)
{
  if (viewport.IsPointInside(p))
    return 0;

  m2::RectD r = viewport;
  r.Scale(3);
  if (r.IsPointInside(p))
    return 1;

  r = viewport;
  r.Scale(5);
  if (r.IsPointInside(p))
    return 2;

  return 3;
}

bool IntermediateResult::StrictEqualF::operator()(IntermediateResult const & r) const
{
  if (m_r.m_resultType == r.m_resultType && m_r.m_resultType == RESULT_FEATURE)
  {
    if (m_r.m_str == r.m_str && m_r.GetBestType() == r.GetBestType())
    {
      // 100.0m - distance between equal features
      return fabs(m_r.m_distance - r.m_distance) < 100.0;
    }
  }

  return false;
}

namespace
{
  uint8_t FirstLevelIndex(uint32_t t)
  {
    uint8_t v;
    VERIFY ( ftype::GetValue(t, 0, v), (t) );
    return v;
  }

  class IsLinearChecker
  {
    static size_t const m_count = 2;
    uint8_t m_index[m_count];

  public:
    IsLinearChecker()
    {
      char const * arr[] = { "highway", "waterway" };
      STATIC_ASSERT ( ARRAY_SIZE(arr) == m_count );

      ClassifObject const * c = classif().GetRoot();
      for (size_t i = 0; i < m_count; ++i)
        m_index[i] = static_cast<uint8_t>(c->BinaryFind(arr[i]).GetIndex());
    }

    bool IsMy(uint8_t ind) const
    {
      for (size_t i = 0; i < m_count; ++i)
        if (ind == m_index[i])
          return true;

      return false;
    }
  };
}

bool IntermediateResult::LessLinearTypesF::operator()
          (IntermediateResult const & r1, IntermediateResult const & r2) const
{
  if (r1.m_resultType != r2.m_resultType)
    return (r1.m_resultType < r2.m_resultType);

  if (r1.m_str != r2.m_str)
    return (r1.m_str < r2.m_str);

  if (r1.GetBestType() != r2.GetBestType())
    return (r1.GetBestType() < r2.GetBestType());

  // Should stay the best feature, after unique, so add this criteria:

  if (r1.m_searchRank != r2.m_searchRank)
    return (r1.m_searchRank > r2.m_searchRank);
  return (r1.m_distance < r2.m_distance);
}

bool IntermediateResult::EqualLinearTypesF::operator()
          (IntermediateResult const & r1, IntermediateResult const & r2) const
{
  if (r1.m_resultType == r2.m_resultType && r1.m_str == r2.m_str)
  {
    // filter equal linear features
    static IsLinearChecker checker;
    return (r1.GetBestType() == r2.GetBestType() &&
            checker.IsMy(FirstLevelIndex(r1.GetBestType())));
  }

  return false;
}

string IntermediateResult::DebugPrint() const
{
  string res("IntermediateResult: ");
  res += "Name: " + m_str;
  res += "; Type: " + ::DebugPrint(GetBestType());
  res += "; Rank: " + ::DebugPrint(m_searchRank);
  res += "; Viewport distance: " + ::DebugPrint(m_viewportDistance);
  res += "; Distance: " + ::DebugPrint(m_distance);
  return res;
}

string IntermediateResult::GetFeatureType(CategoriesT const * pCat) const
{
  uint32_t const type = GetBestType();

  if (pCat)
  {
    for (CategoriesT::const_iterator i = pCat->begin(); i != pCat->end(); ++i)
    {
      if (i->second == type)
        return strings::ToUtf8(i->first);
    }
  }

  string s = classif().GetFullObjectName(type);

  // remove ending dummy symbol
  ASSERT ( !s.empty(), () );
  s.resize(s.size()-1);

  // replace separator
  replace(s.begin(), s.end(), '|', '-');
  return s;
}

void IntermediateResult::RegionInfo::GetRegion(
    storage::CountryInfoGetter const * pInfo, storage::CountryInfo & info) const
{
  if (!m_file.empty())
    pInfo->GetRegionInfo(m_file, info);
  else if (m_valid)
    pInfo->GetRegionInfo(m_point, info);
}

}  // namespace search::impl
}  // namespace search
<commit_msg>[search] Fix bug with suggestion priority.<commit_after>#include "intermediate_result.hpp"

#include "../storage/country_info.hpp"

#include "../indexer/classificator.hpp"
#include "../indexer/feature.hpp"
#include "../indexer/feature_utils.hpp"
#include "../indexer/mercator.hpp"

#include "../geometry/angles.hpp"
#include "../geometry/distance_on_sphere.hpp"

#include "../base/string_utils.hpp"
#include "../base/logging.hpp"

namespace search
{
namespace impl
{

IntermediateResult::IntermediateResult(m2::RectD const & viewportRect, m2::PointD const & pos,
                                       FeatureType const & f,
                                       string const & displayName, string const & fileName)
  : m_types(f),
    m_str(displayName),
    m_rect(f.GetLimitRect(-2)),
    m_resultType(RESULT_FEATURE)
{
  ASSERT_GREATER(m_types.Size(), 0, ());

  // get region info
  if (!fileName.empty())
    m_region.SetName(fileName);
  else
  {
    if (f.GetFeatureType() == feature::GEOM_POINT)
      m_region.SetPoint(f.GetCenter());
  }

  CalcCommonParams(viewportRect, pos);
  m_searchRank = feature::GetSearchRank(m_types, m_rect.Center(), f.GetPopulation());
}

IntermediateResult::IntermediateResult(m2::RectD const & viewportRect, m2::PointD const & pos,
                                       double lat, double lon, double precision)
  : m_str("(" + strings::to_string(lat) + ", " + strings::to_string(lon) + ")"),
    m_rect(MercatorBounds::LonToX(lon - precision), MercatorBounds::LatToY(lat - precision),
           MercatorBounds::LonToX(lon + precision), MercatorBounds::LatToY(lat + precision)),
    m_resultType(RESULT_LATLON), m_searchRank(0)
{
  CalcCommonParams(viewportRect, pos);

  // get region info
  m_region.SetPoint(m2::PointD(MercatorBounds::LonToX(lon),
                               MercatorBounds::LatToY(lat)));
}

void IntermediateResult::CalcCommonParams(m2::RectD const & viewportRect, m2::PointD const & pos)
{
  m2::PointD const center = m_rect.Center();

  // Check if point is valid (see Query::empty_pos_value).
  if (pos.x > -500 && pos.y > -500)
  {
    ASSERT ( my::between_s(-180.0, 180.0, pos.x), (pos.x) );
    ASSERT ( my::between_s(-180.0, 180.0, pos.y), (pos.y) );

    m_distance = ResultDistance(pos, center);
  }
  else
  {
    // empty destance
    m_distance = -1.0;
  }

  m_viewportDistance = ViewportDistance(viewportRect, center);
}

IntermediateResult::IntermediateResult(string const & name, int penalty)
  : m_str(name), m_completionString(name + " "),
    // Categories should always be first.
    m_distance(-1000.0),    // smallest distance :)
    m_viewportDistance(0),  // closest to viewport
    m_resultType(RESULT_CATEGORY),
    m_searchRank(0)         // best rank
{
}

/*
bool IntermediateResult::LessOrderF::operator()
          (IntermediateResult const & r1, IntermediateResult const & r2) const
{
  if (r1.m_resultType != r2.m_resultType)
    return (r1.m_resultType < r2.m_resultType);

  if (r1.m_searchRank != r2.m_searchRank)
    return (r1.m_searchRank > r2.m_searchRank);

  return (r1.m_distance < r2.m_distance);
}
*/

bool IntermediateResult::LessRank(IntermediateResult const & r1, IntermediateResult const & r2)
{
  return (r1.m_searchRank > r2.m_searchRank);
}

bool IntermediateResult::LessDistance(IntermediateResult const & r1, IntermediateResult const & r2)
{
  return (r1.m_distance < r2.m_distance);

  /*
  if (r1.m_distance != r2.m_distance)
    return (r1.m_distance < r2.m_distance);
  else
    return LessRank(r1, r2);
  */
}

bool IntermediateResult::LessViewportDistance(IntermediateResult const & r1, IntermediateResult const & r2)
{
  return (r1.m_viewportDistance < r2.m_viewportDistance);

  /*
  if (r1.m_viewportDistance != r2.m_viewportDistance)
    return (r1.m_viewportDistance < r2.m_viewportDistance);
  else
    return LessRank(r1, r2);
  */
}

Result IntermediateResult::GenerateFinalResult(
    storage::CountryInfoGetter const * pInfo,
    CategoriesT const * pCat) const
{
  storage::CountryInfo info;
  m_region.GetRegion(pInfo, info);

  switch (m_resultType)
  {
  case RESULT_FEATURE:
    return Result(m_str, info.m_name, info.m_flag, GetFeatureType(pCat)
              #ifdef DEBUG
                  + ' ' + strings::to_string(static_cast<int>(m_searchRank))
              #endif
                  ,
                  GetBestType(), feature::GetFeatureViewport(m_types, m_rect),
                  m_distance);

  case RESULT_LATLON:
    return Result(m_str, info.m_name, info.m_flag, GetFeatureType(pCat),
                  0, m_rect, m_distance);

  default:
    ASSERT_EQUAL ( m_resultType, RESULT_CATEGORY, () );
    return Result(m_str, m_completionString);
  }
}

double IntermediateResult::ResultDistance(m2::PointD const & a, m2::PointD const & b)
{
  return ms::DistanceOnEarth(MercatorBounds::YToLat(a.y), MercatorBounds::XToLon(a.x),
                             MercatorBounds::YToLat(b.y), MercatorBounds::XToLon(b.x));
}

double IntermediateResult::ResultDirection(m2::PointD const & a, m2::PointD const & b)
{
  return ang::AngleTo(a, b);
}

int IntermediateResult::ViewportDistance(m2::RectD const & viewport, m2::PointD const & p)
{
  if (viewport.IsPointInside(p))
    return 0;

  m2::RectD r = viewport;
  r.Scale(3);
  if (r.IsPointInside(p))
    return 1;

  r = viewport;
  r.Scale(5);
  if (r.IsPointInside(p))
    return 2;

  return 3;
}

bool IntermediateResult::StrictEqualF::operator()(IntermediateResult const & r) const
{
  if (m_r.m_resultType == r.m_resultType && m_r.m_resultType == RESULT_FEATURE)
  {
    if (m_r.m_str == r.m_str && m_r.GetBestType() == r.GetBestType())
    {
      // 100.0m - distance between equal features
      return fabs(m_r.m_distance - r.m_distance) < 100.0;
    }
  }

  return false;
}

namespace
{
  uint8_t FirstLevelIndex(uint32_t t)
  {
    uint8_t v;
    VERIFY ( ftype::GetValue(t, 0, v), (t) );
    return v;
  }

  class IsLinearChecker
  {
    static size_t const m_count = 2;
    uint8_t m_index[m_count];

  public:
    IsLinearChecker()
    {
      char const * arr[] = { "highway", "waterway" };
      STATIC_ASSERT ( ARRAY_SIZE(arr) == m_count );

      ClassifObject const * c = classif().GetRoot();
      for (size_t i = 0; i < m_count; ++i)
        m_index[i] = static_cast<uint8_t>(c->BinaryFind(arr[i]).GetIndex());
    }

    bool IsMy(uint8_t ind) const
    {
      for (size_t i = 0; i < m_count; ++i)
        if (ind == m_index[i])
          return true;

      return false;
    }
  };
}

bool IntermediateResult::LessLinearTypesF::operator()
          (IntermediateResult const & r1, IntermediateResult const & r2) const
{
  if (r1.m_resultType != r2.m_resultType)
    return (r1.m_resultType < r2.m_resultType);

  if (r1.m_str != r2.m_str)
    return (r1.m_str < r2.m_str);

  if (r1.GetBestType() != r2.GetBestType())
    return (r1.GetBestType() < r2.GetBestType());

  // Should stay the best feature, after unique, so add this criteria:

  if (r1.m_searchRank != r2.m_searchRank)
    return (r1.m_searchRank > r2.m_searchRank);
  return (r1.m_distance < r2.m_distance);
}

bool IntermediateResult::EqualLinearTypesF::operator()
          (IntermediateResult const & r1, IntermediateResult const & r2) const
{
  if (r1.m_resultType == r2.m_resultType && r1.m_str == r2.m_str)
  {
    // filter equal linear features
    static IsLinearChecker checker;
    return (r1.GetBestType() == r2.GetBestType() &&
            checker.IsMy(FirstLevelIndex(r1.GetBestType())));
  }

  return false;
}

string IntermediateResult::DebugPrint() const
{
  string res("IntermediateResult: ");
  res += "Name: " + m_str;
  res += "; Type: " + ::DebugPrint(GetBestType());
  res += "; Rank: " + ::DebugPrint(m_searchRank);
  res += "; Viewport distance: " + ::DebugPrint(m_viewportDistance);
  res += "; Distance: " + ::DebugPrint(m_distance);
  return res;
}

string IntermediateResult::GetFeatureType(CategoriesT const * pCat) const
{
  uint32_t const type = GetBestType();

  if (pCat)
  {
    for (CategoriesT::const_iterator i = pCat->begin(); i != pCat->end(); ++i)
    {
      if (i->second == type)
        return strings::ToUtf8(i->first);
    }
  }

  string s = classif().GetFullObjectName(type);

  // remove ending dummy symbol
  ASSERT ( !s.empty(), () );
  s.resize(s.size()-1);

  // replace separator
  replace(s.begin(), s.end(), '|', '-');
  return s;
}

void IntermediateResult::RegionInfo::GetRegion(
    storage::CountryInfoGetter const * pInfo, storage::CountryInfo & info) const
{
  if (!m_file.empty())
    pInfo->GetRegionInfo(m_file, info);
  else if (m_valid)
    pInfo->GetRegionInfo(m_point, info);
}

}  // namespace search::impl
}  // namespace search
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
/*
 * Copyright (C) 2014 the FFLAS-FFPACK group
 *
 * Written by   Bastien Vialla<bastien.vialla@lirmm.fr>
 * Brice Boyer (briceboyer) <boyer.brice@gmail.com>
 *
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK 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
 * ========LICENCE========
 *.
 */

#ifndef __FFLASFFPACK_fflas_ffpack_utils_simd256_INL
#define __FFLASFFPACK_fflas_ffpack_utils_simd256_INL

struct Simd256fp_base {
#if defined(__FFLASFFPACK_HAVE_AVX2_INSTRUCTIONS) or defined(__FFLASFFPACK_HAVE_AVX_INSTRUCTIONS)

	/*
	* Shuffle 128-bits selected by imm8 from a and b, and store the results in dst.
	* Args   :	[a0, a1]
	*			[b0, b1]
	* Return : [s[0..3]?a0:a1:b0:b1, s[4..7]?a0:a1:b0:b1]
	*/
	template<int s>
	static INLINE CONST __m256d permute128(const __m256d a, const __m256d b) {
		return _mm256_permute2f128_pd(a, b, s);
	}

	template<int s>
	static INLINE CONST __m256 permute128(const __m256 a, const __m256 b) {
		return _mm256_permute2f128_ps(a, b, s);
	}

	/*
	* Unpack and interleave 128-bit integers from the low half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a0, b0] int128_t
	*/
	static INLINE CONST __m256d unpacklo128(const __m256d a, const __m256d b) { return permute128<0x20>(a, b); }
	static INLINE CONST __m256 unpacklo128(const __m256 a, const __m256 b) { return permute128<0x20>(a, b); }

	/*
	* Unpack and interleave 128-bit integers from the high half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a1, b1] int128_t
	*/
	static INLINE CONST __m256d unpackhi128(const __m256d a, const __m256d b) { return permute128<0x31>(a, b); }
	static INLINE CONST __m256 unpackhi128(const __m256 a, const __m256 b) { return permute128<0x31>(a, b); }

#endif
};

struct Simd256i_base {

	/*
	* alias to 256 bit simd register
	*/
	using vect_t = __m256i;

	/*
	*  Return vector of type vect_t with all elements set to zero
	*  Return [0, ...,0]
	*/
	static INLINE CONST vect_t zero() { return _mm256_setzero_si256(); }

#if defined(__FFLASFFPACK_HAVE_AVX2_INSTRUCTIONS) or defined(__FFLASFFPACK_HAVE_AVX_INSTRUCTIONS)

	/*
	* Shift packed 128-bit integers in a left by s bits while shifting in zeros, and store the results in vect_t.
	* Args   : [a0, a1] int128_t
	* Return : [a0 << (s*8), a1 << (s*8)] int128_t
	*/
	template<uint8_t s>
	static INLINE CONST vect_t sll128(const vect_t a) { return _mm256_bslli_epi128(a, s); }

	/*
	* Shift packed 128-bit integers in a right by s while shifting in zeros, and store the results in vect_t.
	* Args   : [a0, a1] int128_t
	* Return : [a0 << (s*8), a1 << (s*8)] int128_t
	*/
	template<uint8_t s>
	static INLINE CONST vect_t srl128(const vect_t a) { return _mm256_bsrli_epi128(a, s); }

	/*
	* Compute the bitwise AND and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 AND b0, ..., a255 AND b255]
	*/
	static INLINE CONST vect_t vand(const vect_t a, const vect_t b) { return _mm256_and_si256(b, a); }

	/*
	* Compute the bitwise OR and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 OR b0, ..., a255 OR b255]
	*/
	static INLINE CONST vect_t vor(const vect_t a, const vect_t b) { return _mm256_or_si256(b, a); }

	/*
	* Compute the bitwise XOR and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 XOR b0, ..., a255 XOR b255]
	*/
	static INLINE CONST vect_t vxor(const vect_t a, const vect_t b) { return _mm256_xor_si256(b, a); }

	/*
	* Compute the bitwise AND NOT and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 AND (NOT b0), ..., a255 AND (NOT b255)]
	*/
	static INLINE CONST vect_t vandnot(const vect_t a, const vect_t b) { return _mm256_andnot_si256(b, a); }

	/*
	* Shuffle 128-bit integers in a and b using the control in imm8, and store the results in dst.
	* Args   :	[a0, a1] int128_t
	*			[b0, b1] int128_t
	* Return : [s[0..3]?a0:a1:b0:b1, s[4..7]?a0:a1:b0:b1] int128_t
	*/
	template<int s>
	static INLINE CONST vect_t permute128(const vect_t a, const vect_t b) {
		return _mm256_permute2x128_si256(a, b, s);
	}

	/*
	* Unpack and interleave 128-bit integers from the low half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a0, b0] int128_t
	*/
	static INLINE CONST vect_t unpacklo128(const vect_t a, const vect_t b) { return permute128<0x20>(a, b); }

	/*
	* Unpack and interleave 128-bit integers from the high half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a1, b1] int128_t
	*/
	static INLINE CONST vect_t unpackhi128(const vect_t a, const vect_t b) { return permute128<0x31>(a, b); }
#endif
};

template <bool ArithType, bool Int, bool Signed, int Size> struct Simd256_impl;

template <class T>
using Simd256 =
	Simd256_impl<std::is_arithmetic<T>::value, std::is_integral<T>::value, std::is_signed<T>::value, sizeof(T)>;

#include "simd256_float.inl"
#include "simd256_double.inl"

#ifdef SIMD_INT

#if defined(__FFLASFFPACK_HAVE_AVX2_INSTRUCTIONS)
#include "simd256_int64.inl"
#include "simd256_int32.inl"
#include "simd256_int16.inl"
#endif

#endif //#ifdef SIMD_INT

#endif // __FFLASFFPACK_fflas_ffpack_utils_simd256_INL
<commit_msg>Revert "fix FFLAS SIMD FLAGS"<commit_after>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
/*
 * Copyright (C) 2014 the FFLAS-FFPACK group
 *
 * Written by   Bastien Vialla<bastien.vialla@lirmm.fr>
 * Brice Boyer (briceboyer) <boyer.brice@gmail.com>
 *
 *
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK 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
 * ========LICENCE========
 *.
 */

#ifndef __FFLASFFPACK_fflas_ffpack_utils_simd256_INL
#define __FFLASFFPACK_fflas_ffpack_utils_simd256_INL

struct Simd256fp_base {
#if defined(__FFLASFFPACK_HAVE_AVX2_INSTRUCTIONS)

	/*
	* Shuffle 128-bits selected by imm8 from a and b, and store the results in dst.
	* Args   :	[a0, a1]
	*			[b0, b1]
	* Return : [s[0..3]?a0:a1:b0:b1, s[4..7]?a0:a1:b0:b1]
	*/
	template<int s>
	static INLINE CONST __m256d permute128(const __m256d a, const __m256d b) {
		return _mm256_permute2f128_pd(a, b, s);
	}

	template<int s>
	static INLINE CONST __m256 permute128(const __m256 a, const __m256 b) {
		return _mm256_permute2f128_ps(a, b, s);
	}

	/*
	* Unpack and interleave 128-bit integers from the low half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a0, b0] int128_t
	*/
	static INLINE CONST __m256d unpacklo128(const __m256d a, const __m256d b) { return permute128<0x20>(a, b); }
	static INLINE CONST __m256 unpacklo128(const __m256 a, const __m256 b) { return permute128<0x20>(a, b); }

	/*
	* Unpack and interleave 128-bit integers from the high half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a1, b1] int128_t
	*/
	static INLINE CONST __m256d unpackhi128(const __m256d a, const __m256d b) { return permute128<0x31>(a, b); }
	static INLINE CONST __m256 unpackhi128(const __m256 a, const __m256 b) { return permute128<0x31>(a, b); }

#endif
};

struct Simd256i_base {

	/*
	* alias to 256 bit simd register
	*/
	using vect_t = __m256i;

	/*
	*  Return vector of type vect_t with all elements set to zero
	*  Return [0, ...,0]
	*/
	static INLINE CONST vect_t zero() { return _mm256_setzero_si256(); }

#if defined(__FFLASFFPACK_HAVE_AVX2_INSTRUCTIONS)

	/*
	* Shift packed 128-bit integers in a left by s bits while shifting in zeros, and store the results in vect_t.
	* Args   : [a0, a1] int128_t
	* Return : [a0 << (s*8), a1 << (s*8)] int128_t
	*/
	template<uint8_t s>
	static INLINE CONST vect_t sll128(const vect_t a) { return _mm256_bslli_epi128(a, s); }

	/*
	* Shift packed 128-bit integers in a right by s while shifting in zeros, and store the results in vect_t.
	* Args   : [a0, a1] int128_t
	* Return : [a0 << (s*8), a1 << (s*8)] int128_t
	*/
	template<uint8_t s>
	static INLINE CONST vect_t srl128(const vect_t a) { return _mm256_bsrli_epi128(a, s); }

	/*
	* Compute the bitwise AND and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 AND b0, ..., a255 AND b255]
	*/
	static INLINE CONST vect_t vand(const vect_t a, const vect_t b) { return _mm256_and_si256(b, a); }

	/*
	* Compute the bitwise OR and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 OR b0, ..., a255 OR b255]
	*/
	static INLINE CONST vect_t vor(const vect_t a, const vect_t b) { return _mm256_or_si256(b, a); }

	/*
	* Compute the bitwise XOR and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 XOR b0, ..., a255 XOR b255]
	*/
	static INLINE CONST vect_t vxor(const vect_t a, const vect_t b) { return _mm256_xor_si256(b, a); }

	/*
	* Compute the bitwise AND NOT and store the results in vect_t.
	* Args   : [a0, ..., a255]
	*		   [b0, ..., b255]
	* Return : [a0 AND (NOT b0), ..., a255 AND (NOT b255)]
	*/
	static INLINE CONST vect_t vandnot(const vect_t a, const vect_t b) { return _mm256_andnot_si256(b, a); }

	/*
	* Shuffle 128-bit integers in a and b using the control in imm8, and store the results in dst.
	* Args   :	[a0, a1] int128_t
	*			[b0, b1] int128_t
	* Return : [s[0..3]?a0:a1:b0:b1, s[4..7]?a0:a1:b0:b1] int128_t
	*/
	template<int s>
	static INLINE CONST vect_t permute128(const vect_t a, const vect_t b) {
		return _mm256_permute2x128_si256(a, b, s);
	}

	/*
	* Unpack and interleave 128-bit integers from the low half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a0, b0] int128_t
	*/
	static INLINE CONST vect_t unpacklo128(const vect_t a, const vect_t b) { return permute128<0x20>(a, b); }

	/*
	* Unpack and interleave 128-bit integers from the high half of a and b, and store the results in dst.
	* Args   : [a0, a1] int128_t
			   [b0, b1] int128_t
	* Return : [a1, b1] int128_t
	*/
	static INLINE CONST vect_t unpackhi128(const vect_t a, const vect_t b) { return permute128<0x31>(a, b); }
#endif
};

template <bool ArithType, bool Int, bool Signed, int Size> struct Simd256_impl;

template <class T>
using Simd256 =
	Simd256_impl<std::is_arithmetic<T>::value, std::is_integral<T>::value, std::is_signed<T>::value, sizeof(T)>;

#include "simd256_float.inl"
#include "simd256_double.inl"

#ifdef SIMD_INT
// Trop d'instructions SSE manquantes pour les int8_t

#if defined(__FFLASFFPACK_HAVE_AVX2_INSTRUCTIONS)
#include "simd256_int64.inl"
#include "simd256_int32.inl"
#include "simd256_int16.inl"
#endif

#endif //#ifdef SIMD_INT

#endif // __FFLASFFPACK_fflas_ffpack_utils_simd256_INL
<|endoftext|>


<commit_before>/// @file
/// @copyright The code is licensed under the BSD License
///            <http://opensource.org/licenses/BSD-2-Clause>,
///            Copyright (c) 2013-2015 Alexandre Hamez.
/// @author Alexandre Hamez

#include <algorithm> // any_of

#include "support/pn/net.hh"

namespace pnmc { namespace pn {

/*------------------------------------------------------------------------------------------------*/

net::net()
  : name{}, modules{}, root_modules{}, m_places{}, m_transitions{}
{}

/*------------------------------------------------------------------------------------------------*/

const place&
net::add_place(const std::string& pname, valuation_type marking)
{
  const auto cit = places_by<name_index>().find(pname);
  if (cit == places_by<name_index>().end())
  {
    return *places_by<insertion_index>().emplace_back(m_current_place_uid++, pname, marking).first;
  }
  else
  {
    // This place was created before by add_post_place() or add_pre_place().
    // At this time, the marking was not known. We can now update it.
    places_by<name_index>().modify(cit, [&](place& p){p.marking = marking;});
    return *cit;
  }
}

/*------------------------------------------------------------------------------------------------*/

const transition&
net::add_transition(const std::string& tname)
{
  const auto cit = transitions_by<name_index>().find(tname);
  if (cit == transitions_by<name_index>().cend())
  {
    return *transitions_by<name_index>().insert({m_current_transition_uid++, tname}).first;
  }
  else
  {
    return *cit;
  }
}

/*------------------------------------------------------------------------------------------------*/

void
net::add_post_place( const std::string& tname, const std::string& post
                   , valuation_type weight, arc::type ty)
{
  if (ty != arc::type::normal)
  {
    throw std::runtime_error("An output arc of a transition must be normal.");
  }

  const auto it = transitions_by<name_index>().find(tname);
  if (it == transitions_by<name_index>().cend())
  {
    throw std::runtime_error("Adding a post place to a non-existing transition.");
  }

  if (it->post.find(post) != end(it->post))
  {
    // Add weights of arcs with the same direction between the same place and transition.
    m_transitions.modify(it, [&](transition& t)
                             {
                               auto search = t.post.find(post);
                               search->second.weight += weight;
                             });
  }
  else
  {
    m_transitions.modify( it
                        , [&](transition& t)
                          {
                            t.post.emplace_hint(end(t.post), post , pn::arc{weight, ty});
                          });

  }

  if (places_by<name_index>().find(post) == places_by<name_index>().end())
  {
    add_place(post, 0);
  }
  places_by<name_index>().modify( places_by<name_index>().find(post)
                                , [&](place& p)
                                  {
                                    p.pre.emplace_hint(end(p.pre), tname, pn::arc{weight, ty});
                                  });
}

/*------------------------------------------------------------------------------------------------*/

void
net::add_pre_place( const std::string& tname, const std::string& pre
                  , valuation_type weight, arc::type ty)
{
  const auto it = transitions_by<name_index>().find(tname);
  if (it == transitions_by<name_index>().end())
  {
    throw std::runtime_error("Adding a pre place to a non-existing transition.");
  }

  const auto arc_search = it->pre.find(pre);
  if (arc_search != end(it->pre))
  {
    if (arc_search->second.kind != ty)
    {
      throw std::runtime_error
        ("Arcs of different types between a place and a transition are not supported yet.");
    }

    // Add weights of arcs with the same direction between the same place and transition.
    m_transitions.modify(it, [&](transition& t)
                             {
                               auto search = t.pre.find(pre);
                               search->second.weight += weight;
                             });
  }
  else
  {
    m_transitions.modify( it
                        , [&](transition& t)
                          {
                            t.pre.emplace_hint(end(t.pre), pre , pn::arc{weight, ty});
                          });

  }

  if (places_by<name_index>().find(pre) == places_by<name_index>().end())
  {
    add_place(pre, 0);
  }
  places_by<name_index>().modify( places_by<name_index>().find(pre)
                                , [&](place& p)
                                  {
                                    p.post.emplace_hint(end(p.post), tname, pn::arc{weight, ty});
                                  });
}

/*------------------------------------------------------------------------------------------------*/

const net::places_type::index<net::insertion_index>::type&
net::places_by_insertion()
const noexcept
{
  return m_places.get<insertion_index>();
}

/*------------------------------------------------------------------------------------------------*/

const net::places_type::index<net::name_index>::type&
net::places()
const noexcept
{
  return m_places.get<name_index>();
}

/*------------------------------------------------------------------------------------------------*/

const net::transitions_type::index<net::name_index>::type&
net::transitions()
const noexcept
{
  return transitions_by<name_index>();
}

/*------------------------------------------------------------------------------------------------*/

const transition&
net::get_transition_by_uid(std::size_t uid)
const
{
  return *transitions_by<uid_index>().find(uid);
}

/*------------------------------------------------------------------------------------------------*/

void
net::add_time_interval(const std::string& tname, clock_type low, clock_type high)
{
  const auto it = transitions_by<name_index>().find(tname);
  m_transitions.modify(it, [&](transition& t){t.low = low; t.high = high;});
}

/*------------------------------------------------------------------------------------------------*/

bool
net::timed()
const noexcept
{
  return std::any_of( transitions().cbegin(), transitions().cend()
                    , [](const transition& t){return t.timed();});
}

/*------------------------------------------------------------------------------------------------*/

bool
net::enabled(const std::string& tname)
const
{
  const auto search = transitions().find(tname);
  if (search == transitions().cend())
  {
    throw std::invalid_argument("Transition " + tname + " doesn't exist");
  }
  const auto& t = *search;

  for (const auto& arc : t.pre)
  {
    const auto place_cit = places().find(arc.first);
    if (place_cit == end(places()))
    {
      throw std::runtime_error("Place " + arc.first + " doesn't exist");
    }
    const auto& place = *place_cit;
    switch (arc.second.kind)
    {
      case pn::arc::type::normal:
      case pn::arc::type::read:
      {
        if (place.marking < arc.second.weight)
        {
          return false;
        }
        break;
      }

      case pn::arc::type::inhibitor:
      {
        if (place.marking >= arc.second.weight)
        {
          return false;
        }
        break;
      }

      default:
        throw std::runtime_error("Unsupported arc type.");
    }

  }
  return true;
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::pn
<commit_msg>Fix dummy bug: initialize ALL members<commit_after>/// @file
/// @copyright The code is licensed under the BSD License
///            <http://opensource.org/licenses/BSD-2-Clause>,
///            Copyright (c) 2013-2015 Alexandre Hamez.
/// @author Alexandre Hamez

#include <algorithm> // any_of

#include "support/pn/net.hh"

namespace pnmc { namespace pn {

/*------------------------------------------------------------------------------------------------*/

net::net()
  : name{}
  , modules{}
  , root_modules{}
  , format{}
  , m_places{}
  , m_transitions{}
  , m_current_place_uid{0}
  , m_current_transition_uid{0}
{}

/*------------------------------------------------------------------------------------------------*/

const place&
net::add_place(const std::string& pname, valuation_type marking)
{
  const auto cit = places_by<name_index>().find(pname);
  if (cit == places_by<name_index>().end())
  {
    return *places_by<insertion_index>().emplace_back(m_current_place_uid++, pname, marking).first;
  }
  else
  {
    // This place was created before by add_post_place() or add_pre_place().
    // At this time, the marking was not known. We can now update it.
    places_by<name_index>().modify(cit, [&](place& p){p.marking = marking;});
    return *cit;
  }
}

/*------------------------------------------------------------------------------------------------*/

const transition&
net::add_transition(const std::string& tname)
{
  const auto cit = transitions_by<name_index>().find(tname);
  if (cit == transitions_by<name_index>().cend())
  {
    return *transitions_by<name_index>().insert({m_current_transition_uid++, tname}).first;
  }
  else
  {
    return *cit;
  }
}

/*------------------------------------------------------------------------------------------------*/

void
net::add_post_place( const std::string& tname, const std::string& post
                   , valuation_type weight, arc::type ty)
{
  if (ty != arc::type::normal)
  {
    throw std::runtime_error("An output arc of a transition must be normal.");
  }

  const auto it = transitions_by<name_index>().find(tname);
  if (it == transitions_by<name_index>().cend())
  {
    throw std::runtime_error("Adding a post place to a non-existing transition.");
  }

  if (it->post.find(post) != end(it->post))
  {
    // Add weights of arcs with the same direction between the same place and transition.
    m_transitions.modify(it, [&](transition& t)
                             {
                               auto search = t.post.find(post);
                               search->second.weight += weight;
                             });
  }
  else
  {
    m_transitions.modify( it
                        , [&](transition& t)
                          {
                            t.post.emplace_hint(end(t.post), post , pn::arc{weight, ty});
                          });

  }

  if (places_by<name_index>().find(post) == places_by<name_index>().end())
  {
    add_place(post, 0);
  }
  places_by<name_index>().modify( places_by<name_index>().find(post)
                                , [&](place& p)
                                  {
                                    p.pre.emplace_hint(end(p.pre), tname, pn::arc{weight, ty});
                                  });
}

/*------------------------------------------------------------------------------------------------*/

void
net::add_pre_place( const std::string& tname, const std::string& pre
                  , valuation_type weight, arc::type ty)
{
  const auto it = transitions_by<name_index>().find(tname);
  if (it == transitions_by<name_index>().end())
  {
    throw std::runtime_error("Adding a pre place to a non-existing transition.");
  }

  const auto arc_search = it->pre.find(pre);
  if (arc_search != end(it->pre))
  {
    if (arc_search->second.kind != ty)
    {
      throw std::runtime_error
        ("Arcs of different types between a place and a transition are not supported yet.");
    }

    // Add weights of arcs with the same direction between the same place and transition.
    m_transitions.modify(it, [&](transition& t)
                             {
                               auto search = t.pre.find(pre);
                               search->second.weight += weight;
                             });
  }
  else
  {
    m_transitions.modify( it
                        , [&](transition& t)
                          {
                            t.pre.emplace_hint(end(t.pre), pre , pn::arc{weight, ty});
                          });

  }

  if (places_by<name_index>().find(pre) == places_by<name_index>().end())
  {
    add_place(pre, 0);
  }
  places_by<name_index>().modify( places_by<name_index>().find(pre)
                                , [&](place& p)
                                  {
                                    p.post.emplace_hint(end(p.post), tname, pn::arc{weight, ty});
                                  });
}

/*------------------------------------------------------------------------------------------------*/

const net::places_type::index<net::insertion_index>::type&
net::places_by_insertion()
const noexcept
{
  return m_places.get<insertion_index>();
}

/*------------------------------------------------------------------------------------------------*/

const net::places_type::index<net::name_index>::type&
net::places()
const noexcept
{
  return m_places.get<name_index>();
}

/*------------------------------------------------------------------------------------------------*/

const net::transitions_type::index<net::name_index>::type&
net::transitions()
const noexcept
{
  return transitions_by<name_index>();
}

/*------------------------------------------------------------------------------------------------*/

const transition&
net::get_transition_by_uid(std::size_t uid)
const
{
  return *transitions_by<uid_index>().find(uid);
}

/*------------------------------------------------------------------------------------------------*/

void
net::add_time_interval(const std::string& tname, clock_type low, clock_type high)
{
  const auto it = transitions_by<name_index>().find(tname);
  m_transitions.modify(it, [&](transition& t){t.low = low; t.high = high;});
}

/*------------------------------------------------------------------------------------------------*/

bool
net::timed()
const noexcept
{
  return std::any_of( transitions().cbegin(), transitions().cend()
                    , [](const transition& t){return t.timed();});
}

/*------------------------------------------------------------------------------------------------*/

bool
net::enabled(const std::string& tname)
const
{
  const auto search = transitions().find(tname);
  if (search == transitions().cend())
  {
    throw std::invalid_argument("Transition " + tname + " doesn't exist");
  }
  const auto& t = *search;

  for (const auto& arc : t.pre)
  {
    const auto place_cit = places().find(arc.first);
    if (place_cit == end(places()))
    {
      throw std::runtime_error("Place " + arc.first + " doesn't exist");
    }
    const auto& place = *place_cit;
    switch (arc.second.kind)
    {
      case pn::arc::type::normal:
      case pn::arc::type::read:
      {
        if (place.marking < arc.second.weight)
        {
          return false;
        }
        break;
      }

      case pn::arc::type::inhibitor:
      {
        if (place.marking >= arc.second.weight)
        {
          return false;
        }
        break;
      }

      default:
        throw std::runtime_error("Unsupported arc type.");
    }

  }
  return true;
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace pnmc::pn
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html
// Bootstrap CI

#include "Statistics.h"
#include "BootstrapStatistics.h"
#include "MooseEnumItem.h"
#include "MooseEnum.h"
#include "MooseError.h"
#include "MooseRandom.h"
#include "libmesh/auto_ptr.h"
#include "libmesh/parallel.h"
#include "libmesh/parallel_sync.h"

#include "SerializerGuard.h"

namespace Statistics
{

MooseEnum
makeBootstrapCalculatorEnum()
{
  return MooseEnum("percentile=0");
}

std::unique_ptr<const BootstrapCalculator>
makeBootstrapCalculator(const MooseEnum & item,
                        const MooseObject & other,
                        const std::vector<Real> & levels,
                        unsigned int replicates,
                        unsigned int seed)
{

  std::unique_ptr<BootstrapCalculator> ptr = nullptr;
  if (item == "percentile")
    ptr = libmesh_make_unique<Percentile>(other);

  ptr->setLevels(levels);
  ptr->setReplicates(replicates);
  ptr->setSeed(seed);
  if (!ptr)
    ::mooseError("Failed to create Statistics::BootstrapCalculator object for ", item);
  return ptr;
}

BootstrapCalculator::BootstrapCalculator(const MooseObject & other) : libMesh::ParallelObject(other)
{
}

void
BootstrapCalculator::setLevels(std::vector<Real> levels)
{
  mooseAssert(*std::min_element(levels.begin(), levels.end()) > 0,
              "The supplied levels must be greater than zero.");
  mooseAssert(*std::max_element(levels.begin(), levels.end()) < 1,
              "The supplied levels must be less than one");
  _levels = levels;
}

void
BootstrapCalculator::setReplicates(const unsigned int replicates)
{
  _replicates = replicates;
}

void
BootstrapCalculator::setSeed(const unsigned int seed)
{
  _seed = seed;
}

std::vector<Real>
BootstrapCalculator::shuffle(const std::vector<Real> & data,
                             MooseRandom & generator,
                             const bool is_distributed) const
{
  // Size of the local input data
  const std::size_t n_local = data.size();

  // The data to be returned
  std::vector<Real> replicate;

  // REPLICATED data
  if (!is_distributed)
  {
    replicate.resize(n_local);
    for (std::size_t j = 0; j < n_local; ++j)
    {
      auto index = generator.randl(0, 0, n_local);
      replicate[j] = data[index];
    }
  }

  // DISTRIBUTED data
  else
  {
    // Reserve space for storing the local
    replicate.reserve(n_local);

    // Compute the global size of the vector
    std::size_t n_global = n_local;
    _communicator.sum(n_global);

    // Compute the vector data offsets, the scope cleans up the "n_local" vector
    std::vector<std::size_t> offsets(n_processors());
    {
      std::vector<std::size_t> local_sizes;
      _communicator.allgather(n_local, local_sizes);
      for (std::size_t i = 1; i < local_sizes.size(); ++i)
        offsets[i] = offsets[i - 1] + local_sizes[i];
    }

    // Advance the random number generator to the current offset
    for (std::size_t i = 0; i < offsets[processor_id()]; ++i)
      generator.randl(0, 0, n_global);

    // Compute the needs for this processor
    std::unordered_map<processor_id_type, std::vector<std::size_t>> needs;
    for (std::size_t i = 0; i < n_local; ++i)
    {
      auto index = generator.randl(0, 0, n_global);
      // iterator to first element in range that is GREATER THAN index
      auto rank = std::upper_bound(offsets.begin(), offsets.end(), index);
      auto rk = std::distance(offsets.begin(), rank) - 1;
      needs[rk].push_back(index - offsets[rk]);
    }

    // Advance the random number generator to the end of the global vector
    for (std::size_t i = offsets[processor_id() + 1]; i < n_global; ++i)
      generator.randl(0, 0, n_global);

    // Collect the values to be returned to the various processors
    std::unordered_map<processor_id_type, std::vector<Real>> returns;
    auto return_functor = [&data, &returns](processor_id_type pid,
                                            const std::vector<std::size_t> & indices) {
      auto & returns_pid = returns[pid];
      returns_pid.reserve(indices.size());
      for (auto idx : indices)
        returns_pid.push_back(data[idx]);
    };
    Parallel::push_parallel_vector_data(_communicator, needs, return_functor);

    // Receive shuffled values from the various processors
    auto recv_functor = [&replicate](processor_id_type /*pid*/, const std::vector<Real> & values) {
      replicate.insert(replicate.end(), values.begin(), values.end());
    };
    Parallel::push_parallel_vector_data(_communicator, returns, recv_functor);
  }

  return replicate;
}

// PERCENTILE //////////////////////////////////////////////////////////////////////////////////////
Percentile::Percentile(const MooseObject & other) : BootstrapCalculator(other) {}

std::vector<Real>
Percentile::compute(const std::vector<Real> & data,
                    const Calculator & calc,
                    const bool is_distributed) const
{
  MooseRandom generator;
  generator.seed(0, _seed);

  // Compute replicate statistics
  std::vector<Real> values(_replicates);
  for (std::size_t i = 0; i < _replicates; ++i)
  {
    std::vector<Real> replicate = shuffle(data, generator, is_distributed);
    values[i] = calc.compute(replicate, is_distributed);
  }
  std::sort(values.begin(), values.end());

  // Extract percentiles
  std::vector<Real> output;
  for (const Real & level : _levels)
  {
    long unsigned int index = std::lrint(level * (_replicates - 1));
    output.push_back(values[index]);
  }

  return output;
}

} // namespace
<commit_msg>Add suggestions from review<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html
// Bootstrap CI

#include "Statistics.h"
#include "BootstrapStatistics.h"
#include "MooseEnumItem.h"
#include "MooseEnum.h"
#include "MooseError.h"
#include "MooseRandom.h"
#include "libmesh/auto_ptr.h"
#include "libmesh/parallel.h"
#include "libmesh/parallel_sync.h"

#include "SerializerGuard.h"

namespace Statistics
{

MooseEnum
makeBootstrapCalculatorEnum()
{
  return MooseEnum("percentile=0");
}

std::unique_ptr<const BootstrapCalculator>
makeBootstrapCalculator(const MooseEnum & item,
                        const MooseObject & other,
                        const std::vector<Real> & levels,
                        unsigned int replicates,
                        unsigned int seed)
{

  std::unique_ptr<BootstrapCalculator> ptr = nullptr;
  if (item == "percentile")
    ptr = libmesh_make_unique<Percentile>(other);

  ptr->setLevels(levels);
  ptr->setReplicates(replicates);
  ptr->setSeed(seed);
  if (!ptr)
    ::mooseError("Failed to create Statistics::BootstrapCalculator object for ", item);
  return ptr;
}

BootstrapCalculator::BootstrapCalculator(const MooseObject & other) : libMesh::ParallelObject(other)
{
}

void
BootstrapCalculator::setLevels(std::vector<Real> levels)
{
  mooseAssert(*std::min_element(levels.begin(), levels.end()) > 0,
              "The supplied levels must be greater than zero.");
  mooseAssert(*std::max_element(levels.begin(), levels.end()) < 1,
              "The supplied levels must be less than one");
  _levels = levels;
}

void
BootstrapCalculator::setReplicates(const unsigned int replicates)
{
  _replicates = replicates;
}

void
BootstrapCalculator::setSeed(const unsigned int seed)
{
  _seed = seed;
}

std::vector<Real>
BootstrapCalculator::shuffle(const std::vector<Real> & data,
                             MooseRandom & generator,
                             const bool is_distributed) const
{
  // Size of the local input data
  const std::size_t n_local = data.size();

  // The data to be returned
  std::vector<Real> replicate;

  // REPLICATED data
  if (!is_distributed)
  {
    replicate.resize(n_local);
    for (std::size_t j = 0; j < n_local; ++j)
    {
      auto index = generator.randl(0, 0, n_local);
      replicate[j] = data[index];
    }
  }

  // DISTRIBUTED data
  else
  {
    // Reserve space for storing the local
    replicate.reserve(n_local);

    // Compute the global size of the vector
    std::size_t n_global = n_local;
    _communicator.sum(n_global);

    // Compute the vector data offsets, the scope cleans up the "n_local" vector
    std::vector<std::size_t> offsets(n_processors());
    {
      std::vector<std::size_t> local_sizes;
      _communicator.allgather(n_local, local_sizes);
      for (std::size_t i = 1; i < local_sizes.size(); ++i)
        offsets[i] = offsets[i - 1] + local_sizes[i];
    }

    // Advance the random number generator to the current offset
    for (std::size_t i = 0; i < offsets[processor_id()]; ++i)
      generator.randl(0, 0, n_global);

    // Compute the needs for this processor
    std::unordered_map<processor_id_type, std::vector<std::size_t>> needs;
    for (std::size_t i = 0; i < n_local; ++i)
    {
      auto index = generator.randl(0, 0, n_global);
      // iterator to first element in range that is GREATER THAN index
      auto rank = std::upper_bound(offsets.begin(), offsets.end(), index);
      auto rk = std::distance(offsets.begin(), rank) - 1;
      needs[rk].push_back(index - offsets[rk]);
    }

    // Advance the random number generator to the end of the global vector
    for (std::size_t i = offsets[processor_id()] + n_local; i < n_global; ++i)
      generator.randl(0, 0, n_global);

    // Collect the values to be returned to the various processors
    std::unordered_map<processor_id_type, std::vector<Real>> returns;
    auto return_functor = [&data, &returns](processor_id_type pid,
                                            const std::vector<std::size_t> & indices) {
      auto & returns_pid = returns[pid];
      for (auto idx : indices)
        returns_pid.push_back(data[idx]);
    };
    Parallel::push_parallel_vector_data(_communicator, needs, return_functor);

    // Receive shuffled values from the various processors
    auto recv_functor = [&replicate](processor_id_type /*pid*/, const std::vector<Real> & values) {
      replicate.insert(replicate.end(), values.begin(), values.end());
    };
    Parallel::push_parallel_vector_data(_communicator, returns, recv_functor);
  }

  return replicate;
}

// PERCENTILE //////////////////////////////////////////////////////////////////////////////////////
Percentile::Percentile(const MooseObject & other) : BootstrapCalculator(other) {}

std::vector<Real>
Percentile::compute(const std::vector<Real> & data,
                    const Calculator & calc,
                    const bool is_distributed) const
{
  MooseRandom generator;
  generator.seed(0, _seed);

  // Compute replicate statistics
  std::vector<Real> values(_replicates);
  for (std::size_t i = 0; i < _replicates; ++i)
  {
    std::vector<Real> replicate = shuffle(data, generator, is_distributed);
    values[i] = calc.compute(replicate, is_distributed);
  }
  std::sort(values.begin(), values.end());

  // Extract percentiles
  std::vector<Real> output;
  for (const Real & level : _levels)
  {
    long unsigned int index = std::lrint(level * (_replicates - 1));
    output.push_back(values[index]);
  }

  return output;
}

} // namespace
<|endoftext|>