Exemple #1
0
void producer(void)
{
	int i;
	unsigned long long start, end, sum = 0, avg, dev = 0;


	for (i = 0 ; i < RB_ITER ; i++) {
		rdtscll(start);
		__p();
		rdtscll(end);
		meas[i] = end - start;
		sum += meas[i];
	}
	avg = sum/RB_ITER;
	for (i = 0 ; i < RB_ITER ; i++) {
		unsigned long long diff = (meas[i] > avg) ? 
			meas[i] - avg : 
			avg - meas[i];
		dev += (diff*diff);
	}
	dev /= RB_ITER;
	printf("round trip deviation^2 = %llu\n", dev);

	printf("RPC pipe: Producer: %llu\n", avg);
}
strstreambuf::pos_type
strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
{
    off_type __p(-1);
    bool pos_in = (__which & ios::in) != 0;
    bool pos_out = (__which & ios::out) != 0;
    if (pos_in || pos_out)
    {
        if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
        {
            off_type newoff = __sp;
            char* seekhigh = epptr() ? epptr() : egptr();
            if (0 <= newoff && newoff <= seekhigh - eback())
            {
                char* newpos = eback() + newoff;
                if (pos_in)
                    setg(eback(), newpos, _VSTD::max(newpos, egptr()));
                if (pos_out)
                {
                    // min(pbase, newpos), newpos, epptr()
                    off_type temp = epptr() - newpos;
                    setp(min(pbase(), newpos), epptr());
                    pbump(static_cast<int>((epptr() - pbase()) - temp));
                }
                __p = newoff;
            }
        }
    }
    return pos_type(__p);
}
strstreambuf::pos_type
strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
{
    off_type __p(-1);
    bool pos_in = (__which & ios::in) != 0;
    bool pos_out = (__which & ios::out) != 0;
    bool legal = false;
    switch (__way)
    {
    case ios::beg:
    case ios::end:
        if (pos_in || pos_out)
            legal = true;
        break;
    case ios::cur:
        if (pos_in != pos_out)
            legal = true;
        break;
    }
    if (pos_in && gptr() == nullptr)
        legal = false;
    if (pos_out && pptr() == nullptr)
        legal = false;
    if (legal)
    {
        off_type newoff;
        char* seekhigh = epptr() ? epptr() : egptr();
        switch (__way)
        {
        case ios::beg:
            newoff = 0;
            break;
        case ios::cur:
            newoff = (pos_in ? gptr() : pptr()) - eback();
            break;
        case ios::end:
            newoff = seekhigh - eback();
            break;
        default:
            return pos_type(off_type(-1));
        }
        newoff += __off;
        if (0 <= newoff && newoff <= seekhigh - eback())
        {
            char* newpos = eback() + newoff;
            if (pos_in)
                setg(eback(), newpos, _VSTD::max(newpos, egptr()));
            if (pos_out)
            {
                // min(pbase, newpos), newpos, epptr()
                __off = epptr() - newpos;
                setp(min(pbase(), newpos), epptr());
                pbump(static_cast<int>((epptr() - pbase()) - __off));
            }
            __p = newoff;
        }
    }
    return pos_type(__p);
}
Exemple #4
0
PTile pf_synth(bool negative, bool inverted, long long epoch, unsigned long long lattice){
  //check for overflow condition.
  if (epoch > ((1 << (PENV->epochbits - 1)) - 1)){
    if (negative){
      return (inverted ? __nfew : __nmany);
    } else {
      return (inverted ? __few : __many);
    }
  }

  PTile temp = __p(((epoch << PENV->latticebits | lattice) * (PENV->increment)) | __one);
  if (inverted) {temp = tile_multiplicativeinverse(temp);};
  if (negative) {temp = tile_additiveinverse(temp);};
  return temp;
}
Exemple #5
0
typename Evaluator<iDim, Iterator, Pset, ExprT>::eval_element_type
Evaluator<iDim, Iterator, Pset, ExprT>::operator()( mpl::size_t<MESH_FACES> ) const
{

    boost::timer __timer;

    VLOG(2) << "evaluator(MESH_FACES) " << "\n";
    //
    // a few typedefs
    //

    // mesh element
    typedef typename mesh_element_type::entity_type geoelement_type;
    //typedef typename geoelement_type::face_type face_type;
    typedef mesh_element_type face_type;

    // geometric mapping context
    typedef typename geoelement_type::gm_type gm_type;
    typedef boost::shared_ptr<gm_type> gm_ptrtype;
    typedef typename geoelement_type::gm1_type gm1_type;
    typedef boost::shared_ptr<gm1_type> gm1_ptrtype;

    typedef typename gm_type::template Context<context, geoelement_type> gmc_type;
    typedef boost::shared_ptr<gmc_type> gmc_ptrtype;
    typedef fusion::map<fusion::pair<vf::detail::gmc<0>, gmc_ptrtype> > map_gmc_type;
    typedef typename gm1_type::template Context<context, geoelement_type> gmc1_type;
    typedef boost::shared_ptr<gmc1_type> gmc1_ptrtype;
    typedef fusion::map<fusion::pair<vf::detail::gmc<0>, gmc1_ptrtype> > map_gmc1_type;

    // expression
    //typedef typename expression_type::template tensor<map_gmc_type,fecontext_type> t_expr_type;
    //typedef decltype( basis_type::isomorphism( M_expr ) ) the_expression_type;
    typedef expression_type the_expression_type;
    typedef typename boost::remove_reference<typename boost::remove_const<the_expression_type>::type >::type iso_expression_type;
    typedef typename iso_expression_type::template tensor<map_gmc_type> t_expr_type;
    typedef typename iso_expression_type::template tensor<map_gmc1_type> t_expr1_type;
    typedef typename t_expr_type::shape shape;

    //
    // start
    //

    iterator_type __face_it, __face_en;
    boost::tie( boost::tuples::ignore, __face_it, __face_en ) = M_range;

    int npoints = M_pset.fpoints(0,1).size2();
    element_type __v( M_pset.fpoints(0,1).size2()*std::distance( __face_it, __face_en )*shape::M );
    node_type __p( mesh_element_type::nRealDim, M_pset.fpoints(0,1).size2()*std::distance( __face_it, __face_en ) );
    __v.setZero();
    __p.setZero();
    VLOG(2) << "pset: " << M_pset.fpoints(0,1);
    VLOG(2) << "Checking trivial result...";

    if ( __face_it == __face_en )
        return boost::make_tuple( __v, __p );

    gm_ptrtype __gm( new gm_type );
    gm1_ptrtype __gm1( new gm1_type );



    //
    // Precompute some data in the reference element for
    // geometric mapping and reference finite element
    //
    typedef typename geoelement_type::permutation_type permutation_type;
    typedef typename gm_type::precompute_ptrtype geopc_ptrtype;
    typedef typename gm_type::precompute_type geopc_type;
    typedef typename gm1_type::precompute_ptrtype geopc1_ptrtype;
    typedef typename gm1_type::precompute_type geopc1_type;

    std::vector<std::map<permutation_type, geopc_ptrtype> > __geopc( M_pset.nFaces() );
    std::vector<std::map<permutation_type, geopc1_ptrtype> > __geopc1( M_pset.nFaces() );

    VLOG(2) << "computing geopc...";
    for ( uint16_type __f = 0; __f < M_pset.nFaces(); ++__f )
    {
        for ( permutation_type __p( permutation_type::IDENTITY );
                __p < permutation_type( permutation_type::N_PERMUTATIONS ); ++__p )
        {
            __geopc[__f][__p] = geopc_ptrtype(  new geopc_type( __gm, M_pset.fpoints(__f, __p.value() ) ) );
            __geopc1[__f][__p] = geopc1_ptrtype(  new geopc1_type( __gm1, M_pset.fpoints(__f, __p.value() ) ) );
            DVLOG(2) << "pset " << __f << " : " << M_pset.fpoints(__f, __p.value() );
            CHECK( __geopc[__f][__p]->nPoints()  ) << "invalid number of points for geopc";
            CHECK( __geopc1[__f][__p]->nPoints() ) << "invalid number of points for geopc1";
        }
    }

    uint16_type __face_id = __face_it->pos_first();
    gmc_ptrtype __c( new gmc_type( __gm, __face_it->element( 0 ), __geopc, __face_id ) );
    gmc1_ptrtype __c1( new gmc1_type( __gm1, __face_it->element( 0 ), __geopc1, __face_id ) );

    map_gmc_type mapgmc( fusion::make_pair<vf::detail::gmc<0> >( __c ) );
    t_expr_type expr( M_expr, mapgmc );
    map_gmc1_type mapgmc1( fusion::make_pair<vf::detail::gmc<0> >( __c1 ) );
    t_expr1_type expr1( M_expr, mapgmc1 );




    size_type nbFaceDof = invalid_size_type_value;

    for ( int e = 0; __face_it != __face_en; ++__face_it, ++e )
    {
        FEELPP_ASSERT( __face_it->isOnBoundary() && !__face_it->isConnectedTo1() )
        ( __face_it->marker() )
        ( __face_it->isOnBoundary() )
        ( __face_it->ad_first() )
        ( __face_it->pos_first() )
        ( __face_it->ad_second() )
        ( __face_it->pos_second() )
        ( __face_it->id() ).warn( "inconsistent data face" );
        DVLOG(2) << "[evaluator] FACE_ID = " << __face_it->id()
                      << " element id= " << __face_it->ad_first()
                      << " pos in elt= " << __face_it->pos_first()
                      << " marker: " << __face_it->marker() << "\n";
        DVLOG(2) << "[evaluator] FACE_ID = " << __face_it->id() << " real pts=" << __face_it->G() << "\n";

        uint16_type __face_id = __face_it->pos_first();


        switch ( M_geomap_strategy )
        {
        default:
        case GeomapStrategyType::GEOMAP_OPT:
        case GeomapStrategyType::GEOMAP_HO:
        {
            __c->update( __face_it->element( 0 ), __face_id );
            DVLOG(2) << "[evaluator::GEOMAP_HO|GEOMAP_OPT] FACE_ID = " << __face_it->id() << "  ref pts=" << __c->xRefs() << "\n";
            DVLOG(2) << "[evaluator::GEOMAP_HO|GEOMAP_OPT] FACE_ID = " << __face_it->id() << " real pts=" << __c->xReal() << "\n";

            map_gmc_type mapgmc( fusion::make_pair<vf::detail::gmc<0> >( __c ) );

            expr.update( mapgmc );

            for ( uint16_type p = 0; p < npoints; ++p )
            {
                for ( uint16_type c1 = 0; c1 < mesh_element_type::nRealDim; ++c1 )
                {
                    __p(c1, e*npoints+p) = __c->xReal(p)[c1];
                }

                for ( uint16_type c1 = 0; c1 < shape::M; ++c1 )
                {
                    __v( e*npoints*shape::M+shape::M*p+c1) = expr.evalq( c1, 0, p );
                }
            }
        }
        break;

        case GeomapStrategyType::GEOMAP_O1:
        {
            __c1->update( __face_it->element( 0 ), __face_id );
            DVLOG(2) << "[evaluator::GEOMAP_O1] FACE_ID = " << __face_it->id() << "  ref pts=" << __c1->xRefs() << "\n";
            DVLOG(2) << "[evaluator::GEOMAP_O1] FACE_ID = " << __face_it->id() << " real pts=" << __c1->xReal() << "\n";

            map_gmc1_type mapgmc1( fusion::make_pair<vf::detail::gmc<0> >( __c1 ) );

            expr1.update( mapgmc1 );

            for ( uint16_type p = 0; p < npoints; ++p )
            {
                for ( uint16_type c1 = 0; c1 < mesh_element_type::nRealDim; ++c1 )
                {
                    __p(c1, e*npoints+p) = __c1->xReal(p)[c1];
                }

                for ( uint16_type c1 = 0; c1 < shape::M; ++c1 )
                {
                    __v( e*npoints*shape::M+shape::M*p+c1) = expr1.evalq( c1, 0, p );
                }

            }
        }
        break;
        }

    } // face_it


    return boost::make_tuple( __v, __p );
}
Exemple #6
0
typename Evaluator<iDim, Iterator, Pset, ExprT>::eval_element_type
Evaluator<iDim, Iterator, Pset, ExprT>::operator()( mpl::size_t<MESH_ELEMENTS> ) const
{
    boost::timer __timer;

    typedef typename mesh_element_type::gm_type gm_type;
    typedef typename gm_type::template Context<context, mesh_element_type> gm_context_type;
    typedef typename mesh_element_type::gm1_type gm1_type;
    typedef typename gm1_type::template Context<context, mesh_element_type> gm1_context_type;


    typedef boost::shared_ptr<gm_context_type> gm_context_ptrtype;
    typedef boost::shared_ptr<gm1_context_type> gm1_context_ptrtype;
    typedef fusion::map<fusion::pair<vf::detail::gmc<0>, gm_context_ptrtype> > map_gmc_type;
    typedef fusion::map<fusion::pair<vf::detail::gmc<0>, gm1_context_ptrtype> > map_gmc1_type;
    //typedef typename expression_type::template tensor<map_gmc_type,fusion::map<fusion::pair<vf::detail::gmc<0>,boost::shared_ptr<fecontext_type> > > > t_expr_type;
    //typedef decltype( basis_type::isomorphism( M_expr ) ) the_expression_type;
    typedef expression_type the_expression_type;
    typedef typename boost::remove_reference<typename boost::remove_const<the_expression_type>::type >::type iso_expression_type;
    typedef typename iso_expression_type::template tensor<map_gmc_type> t_expr_type;
    typedef typename iso_expression_type::template tensor<map_gmc1_type> t_expr1_type;
    typedef typename t_expr_type::value_type value_type;

    // we should manipulate the same type of functions on the left and
    // on the right
    //BOOST_STATIC_ASSERT(( boost::is_same<return_value_type, typename functionspace_type::return_value_type>::value ));

    typedef typename t_expr_type::shape shape;


    iterator_type it, en;
    boost::tie( boost::tuples::ignore, it, en ) = M_range;

    int npoints = M_pset.points().size2();
    element_type __v( M_pset.points().size2()*std::distance( it, en )*shape::M );
    node_type __p( mesh_element_type::nDim, M_pset.points().size2()*std::distance( it, en ) );
    __v.setZero();
    __p.setZero();



    // return if no elements
    if ( it == en )
        return boost::make_tuple( __v, __p );

    //
    // Precompute some data in the reference element for
    // geometric mapping and reference finite element
    //
    typename gm_type::precompute_ptrtype __geopc( new typename gm_type::precompute_type( it->gm(),
                                                                                         M_pset.points() ) );
    typename gm1_type::precompute_ptrtype __geopc1( new typename gm1_type::precompute_type( it->gm1(),
                                                                                            M_pset.points() ) );



    gm_context_ptrtype __c( new gm_context_type( it->gm(),*it,__geopc ) );
    gm1_context_ptrtype __c1( new gm1_context_type( it->gm1(),*it,__geopc1 ) );

    map_gmc_type mapgmc( fusion::make_pair<vf::detail::gmc<0> >( __c ) );
    t_expr_type tensor_expr( M_expr, mapgmc );

    map_gmc1_type mapgmc1( fusion::make_pair<vf::detail::gmc<0> >( __c1 ) );

    t_expr1_type tensor_expr1( M_expr, mapgmc1 );

    for ( int e = 0; it!=en ; ++it, ++e )
    {
        switch ( M_geomap_strategy )
        {
        case GeomapStrategyType::GEOMAP_HO:
        {
            __c->update( *it );
            map_gmc_type mapgmc( fusion::make_pair<vf::detail::gmc<0> >( __c ) );
            tensor_expr.update( mapgmc );

            for ( uint16_type p = 0; p < npoints; ++p )
            {
                for ( uint16_type c1 = 0; c1 < mesh_element_type::nDim; ++c1 )
                {
                    __p(c1, e*npoints+p) = __c->xReal(p)[c1];
                }

                for ( uint16_type c1 = 0; c1 < shape::M; ++c1 )
                {
                    __v( e*npoints*shape::M+shape::M*p+c1) = tensor_expr.evalq( c1, 0, p );
                }
            }
        }
        break;

        case GeomapStrategyType::GEOMAP_O1:
        {
            __c1->update( *it );
            map_gmc1_type mapgmc1( fusion::make_pair<vf::detail::gmc<0> >( __c1 ) );
            tensor_expr1.update( mapgmc1 );

            for ( uint16_type p = 0; p < npoints; ++p )
            {
                for ( uint16_type c1 = 0; c1 < mesh_element_type::nDim; ++c1 )
                {
                    __p(c1, e*npoints+p) = __c1->xReal(p)[c1];
                }
                for ( uint16_type c1 = 0; c1 < shape::M; ++c1 )
                {
                    __v( e*npoints*shape::M+shape::M*p+c1) = tensor_expr1.evalq( c1, 0, p );
                }
            }
        }
        break;

        case GeomapStrategyType::GEOMAP_OPT:
        {
            if ( it->isOnBoundary() )
            {
                // HO if on boundary
                __c->update( *it );
                map_gmc_type mapgmc( fusion::make_pair<vf::detail::gmc<0> >( __c ) );
                tensor_expr.update( mapgmc );

                for ( uint16_type p = 0; p < npoints; ++p )
                {
                    for ( uint16_type c1 = 0; c1 < mesh_element_type::nDim; ++c1 )
                    {
                        __p(c1, e*npoints+p) = __c->xReal(p)[c1];
                    }
                    for ( uint16_type c1 = 0; c1 < shape::M; ++c1 )
                    {
                        __v( e*npoints*shape::M+shape::M*p+c1) = tensor_expr.evalq( c1, 0, p );
                    }
                }
            }

            else
            {
                __c1->update( *it );
                map_gmc1_type mapgmc1( fusion::make_pair<vf::detail::gmc<0> >( __c1 ) );
                tensor_expr1.update( mapgmc1 );


                for ( uint16_type p = 0; p < npoints; ++p )
                {
                    for ( uint16_type c1 = 0; c1 < mesh_element_type::nDim; ++c1 )
                    {
                        __p(c1, e*npoints+p) = __c1->xReal(p)[c1];
                    }
                    for ( uint16_type c1 = 0; c1 < shape::M; ++c1 )
                    {
                        __v( e*npoints*shape::M+shape::M*p+c1) = tensor_expr1.evalq( c1, 0, p );
                    }
                }
            }
        }
        break;
        }
    }
    return boost::make_tuple( __v, __p );
}
Exemple #7
0
    void
    modifVec(std::list<ElementRange> const& __r, eltType const& u,vectorType & UnVec,ExprType const& expr,
             size_type rowstart, int ComponentShiftFactor,
             mpl::int_<MESH_FACES> /**/ )
    {
        //using namespace Feel::vf;
        typedef typename eltType::functionspace_type::mesh_type mesh_type;
        typedef typename mesh_type::face_iterator face_iterator;
        typedef typename mesh_type::face_const_iterator face_const_iterator;

        typedef typename mesh_type::element_type geoelement_type;
        typedef typename geoelement_type::face_type face_type;
        // basis
        typedef typename eltType::functionspace_type::fe_type fe_type;

        typedef typename eltType::functionspace_type::dof_type dof_type;

        const size_type context = ExprType::context|vm::POINT;

        // geometric mapping context
        typedef typename mesh_type::gm_type gm_type;
        typedef boost::shared_ptr<gm_type> gm_ptrtype;
        typedef typename gm_type::template Context<context, geoelement_type> gmc_type;
        typedef boost::shared_ptr<gmc_type> gmc_ptrtype;
        typedef fusion::map<fusion::pair<vf::detail::gmc<0>, gmc_ptrtype> > map_gmc_type;

        typedef typename ExprType::template tensor<map_gmc_type> t_expr_type;

        if ( __r.size() == 0 ) return;
        auto __face_it =  __r.begin()->template get<1>();
        auto __face_en =  __r.begin()->template get<2>();
        //if ( __face_it == __face_en ) return;
        bool findAFace = false;
        for( auto lit = __r.begin(), len = __r.end(); lit != len; ++lit )
        {
            __face_it = lit->template get<1>();
            __face_en = lit->template get<2>();
            if ( __face_it != __face_en )
            {
                findAFace=true;
                break;
            }
        }
        if ( !findAFace ) return;

        // get the first face properly connected
        bool findAFaceToInit=false;
        for( auto lit = __r.begin(), len = __r.end(); lit != len; ++lit )
        {
            __face_it = lit->template get<1>();
            __face_en = lit->template get<2>();
            for( ; __face_it != __face_en; ++__face_it )
            {
                if ( boost::unwrap_ref(*__face_it).isConnectedTo0() )
                {
                    findAFaceToInit=true;
                    break;
                }
            }
            if ( findAFaceToInit ) break;
        }
        CHECK( findAFaceToInit ) << "not find a face to init\n";


        size_type nbFaceDof = invalid_size_type_value;
        if ( !fe_type::is_modal )
            nbFaceDof = ( face_type::numVertices * fe_type::nDofPerVertex +
                          face_type::numEdges * fe_type::nDofPerEdge +
                          face_type::numFaces * fe_type::nDofPerFace );
        else
            nbFaceDof = face_type::numVertices * fe_type::nDofPerVertex;



        //dof_type const* __dof = u.functionSpace()->dof().get();
        fe_type const* __fe = u.functionSpace()->fe().get();
        gm_ptrtype __gm( new gm_type );

        //
        // Precompute some data in the reference element for
        // geometric mapping and reference finite element
        //
        typedef typename geoelement_type::permutation_type permutation_type;
        typedef typename gm_type::precompute_ptrtype geopc_ptrtype;
        typedef typename gm_type::precompute_type geopc_type;
        std::vector<std::map<permutation_type, geopc_ptrtype> > __geopc( geoelement_type::numTopologicalFaces );
        for ( uint16_type __f = 0; __f < geoelement_type::numTopologicalFaces; ++__f )
        {
            permutation_type __p( permutation_type::IDENTITY );
            __geopc[__f][__p] = geopc_ptrtype(  new geopc_type( __gm, __fe->points( __f ) ) );
        }

        uint16_type __face_id = __face_it->pos_first();
        gmc_ptrtype __c( new gmc_type( __gm, __face_it->element(0), __geopc, __face_id ) );

        map_gmc_type mapgmc( fusion::make_pair<vf::detail::gmc<0> >( __c ) );
        t_expr_type LExpr( expr, mapgmc );

        std::vector<bool> dofdone( u.functionSpace()->dof()->nLocalDofWithGhost(), false );

        //face_const_iterator __face_it, __face_en;

        for( auto lit = __r.begin(), len = __r.end(); lit != len; ++lit )
        {
            __face_it = lit->template get<1>();
            __face_en = lit->template get<2>();
            for ( ; __face_it != __face_en; ++__face_it )
            {
                uint16_type __face_id = __face_it->pos_first();
                __c->update( __face_it->element(0), __face_id );
                map_gmc_type mapgmc( fusion::make_pair<vf::detail::gmc<0> >( __c ) );
                LExpr.update( mapgmc );

                for (uint c1=0;c1<eltType::nComponents1;c1++)
                    for (uint c2=0;c2<eltType::nComponents2;c2++)
                    {
                        for ( uint16_type l = 0; l < nbFaceDof; ++l )
                        {
                            size_type index = boost::get<0>(u.functionSpace()->dof()->faceLocalToGlobal( __face_it->id(), l, c1 ));
                            if ( dofdone[index] ) continue;
                            size_type thedof =  u.start() + ComponentShiftFactor*index;
                            double __value=LExpr.evalq( c1, c2, l );
                            //u( thedof ) =  __value;
                            UnVec->set(rowstart+thedof,__value);
                            dofdone[index] = true;
                        }
                    }
            }
        }
        //UnVec->close();
    } // modifVec
  void
  lanczos()
  {
    std::cout.precision(std::numeric_limits<_Tp>::digits10);

    // From Pugh..
    int __n_old = 0;
    int __n = -2 - 0.3 * std::log(std::numeric_limits<_Tp>::epsilon());
    std::cout << "n = " << __n << '\n';

    auto __g = __n - _Tp{0.5L};
    std::cout << "g = " << __g << '\n';
    while (__n != __n_old)
      {
	std::cout << '\n';
	std::vector<_Tp> __a;
	for (unsigned int k = 1; k <= __n; ++k)
	  {
	    for (unsigned int j = 1; j <= k; ++j)
              std::cout << "  C(" << std::setw(2) << k
			  << ", " << std::setw(2) << j
			  << ") = " << std::setw(4) << __c(k, j);
            std::cout << '\n';
	  }

	std::cout << '\n';
	auto __prev = std::numeric_limits<_Tp>::max();
	for (unsigned int __k = 0; __k <= __n + 5; ++__k)
	  {
	    auto __curr = __p(__k, __g);
	    if (std::abs(__curr) > std::abs(__prev))
	      {
		__n_old = __n;
		__n = __k;
		__g = __n - _Tp{0.5L};
		break;
	      }
	    __prev = __curr;
	    std::cout << "  p(" << __k << ", " << __g << ") = " << __curr << '\n';
	  }
	std::cout << "n = " << __n << '\n';
      }

    constexpr auto _S_log_sqrt_2pi = 9.189385332046727417803297364056176398620e-1L;

    auto
    __log_gamma_lanczos = [=](_Tp __z) -> _Tp
    {
      auto __fact = _Tp{1};
      auto __sum = _Tp{0.5L} * __p(0, __g);
      for (unsigned int __k = 1; __k < __n; ++__k)
	{
	  __fact *= (__z - __k + 1) / (__z + __k);
	  __sum += __fact * __p(__k, __g);
	}
      return _S_log_sqrt_2pi + std::log(__sum)
	   + (__z + 0.5L) * std::log(__z + __g + 0.5L)
	   - (__z + __g + 0.5L) - std::log(__z);
    };

    std::cout << '\n';
    for (int i = 0; i <= 500; ++i)
      {
	auto z = _Tp{0.01Q} * i;
	std::cout << ' ' << z
		  << ' ' << __log_gamma_lanczos(z)
		  << ' ' << std::lgamma(z)
		  << ' ' << __log_gamma_lanczos(z) - std::lgamma(z) << '\n';
      }
  }
  void
  hankel_transition()
  {
    auto sign = [](int s, int r){return (s + r) % 2 == 1 ? -1 : +1; };
    using rational = _Tp;

    std::cout.precision(std::numeric_limits<_Tp>::digits10);
    auto width = std::cout.precision() + 6;

    __gnu_cxx::_Polynomial<int> poo({0, -2});
    std::vector<__gnu_cxx::_Polynomial<int>> phi;
    std::vector<__gnu_cxx::_Polynomial<int>> psi;
    phi.push_back(__gnu_cxx::_Polynomial<int>(1));
    phi.push_back(__gnu_cxx::_Polynomial<int>(0));
    phi.push_back(__gnu_cxx::_Polynomial<int>({0, -2}));
    psi.push_back(__gnu_cxx::_Polynomial<int>(0));
    psi.push_back(__gnu_cxx::_Polynomial<int>(-1));
    psi.push_back(__gnu_cxx::_Polynomial<int>(0));
    for (int s = 3; s <= 18; ++s)
      {
	phi.push_back(poo * phi[s - 2] -2 * (s - 2) * phi[s - 3]);
	psi.push_back(poo * psi[s - 2] -2 * (s - 2) * psi[s - 3]);
      }
    std::cout << "\nphi polynomial\n";
    for (const auto& p : phi)
      std::cout << p << '\n';
    std::cout << "\npsi polynomial\n";
    for (const auto& p : psi)
      std::cout << p << '\n';
    std::vector<__gnu_cxx::_Polynomial<rational>> A(6);
    std::vector<__gnu_cxx::_Polynomial<rational>> B(6);
    for (int s = 0; s < 6; ++s)
      {
	for (int r = 0; r <= s; ++r)
	  A[s] += phi[2 * s + r] * __gnu_cxx::_Polynomial<rational>(sign(r, s), r);
	std::cout << "A_" << s << ": " << A[s] << '\n';
	for (int r = 0; r <= s; ++r)
	  B[s] += psi[2 * s + r] * __gnu_cxx::_Polynomial<rational>(sign(r, s), r);
	std::cout << "B_" << s << ": " << B[s] << '\n';
      }

    std::vector<__gnu_cxx::_Polynomial<__gnu_cxx::_Rational<long long>>>
    P
    {
      {{1, 1}},
      {{}, {-1, 5}},
      {{}, {}, {3, 35}, {}, {}, {-9, 100}},
      {{-1, 225}, {}, {}, {-173, 3150}, {}, {}, {957, 7000}},
      {{}, {947, 346500}, {}, {}, {5903, 138600}, {}, {}, {-23573, 147000}, {}, {}, {27, 20000}}
    };

    std::vector<__gnu_cxx::_Polynomial<__gnu_cxx::_Rational<long long>>>
    Q
    {
      {{}, {}, {3, 10}},
      {{1, 70}, {}, {}, {-17, 70}},
      {{}, {-37, 3150}, {}, {}, {611, 3150}, {}, {}, {-9, 1000}},
      {{}, {}, {79, 12375}, {}, {}, {-110767, 693000}, {}, {}, {549, 28000}}
    };

    std::vector<__gnu_cxx::_Polynomial<__gnu_cxx::_Rational<long long>>>
    R
    {
      {{1, 1}},
      {{}, {-4, 5}},
      {{}, {}, {57, 70}, {}, {}, {-9, 100}},
      {{23, 3150}, {}, {}, {-2617, 3150}, {}, {}, {699, 3500}},
      {{}, {-1159, 115500}, {}, {}, {3889, 4620}, {}, {}, {-46631, 147000}, {}, {}, {27, 20000}}
    };

    std::vector<__gnu_cxx::_Polynomial<__gnu_cxx::_Rational<long long>>>
    S
    {
      {{-1, 5}, {}, {}, {3, 5}},
      {{}, {1, 5}, {}, {}, {-131, 140}},
      {{}, {}, {-593, 3150}, {}, {}, {5437, 4500}, {}, {}, {-9, 500}},
      {{947, 346500}, {}, {}, {31727, 173250}, {}, {}, {-999443, 693000}, {}, {}, {369, 7000}}
    };

    std::cout << "\nP polynomial\n";
    for (const auto& p : P)
      std::cout << p << '\n';
    std::cout << "\nP values\n";
    for (int i = -100; i <= +100; ++i)
      {
	auto z = _Tp{0.01Q} * i;
	std::cout << std::setw(width) << z;
	for (const auto& p : P)
	  std::cout << std::setw(width) << p(z);
	std::cout << '\n';
      }

    std::cout << "\nQ polynomial\n";
    for (const auto& q : Q)
      std::cout << q << '\n';
    std::cout << "\nQ values\n";
    for (int i = -100; i <= +100; ++i)
      {
	auto z = _Tp{0.01Q} * i;
	std::cout << std::setw(width) << z;
	for (const auto& q : Q)
	  std::cout << std::setw(width) << q(z);
	std::cout << '\n';
      }

    std::cout << "\nR polynomial\n";
    for (const auto& r : R)
      std::cout << r << '\n';
    std::cout << "\nR values\n";
    for (int i = -100; i <= +100; ++i)
      {
	auto z = _Tp{0.01Q} * i;
	std::cout << std::setw(width) << z;
	for (const auto& r : R)
	  std::cout << std::setw(width) << r(z);
	std::cout << '\n';
      }

    std::cout << "\nS polynomial\n";
    for (const auto& s : S)
      std::cout << s << '\n';
    std::cout << "\nS values\n";
    for (int i = -100; i <= +100; ++i)
      {
	auto z = _Tp{0.01Q} * i;
	std::cout << std::setw(width) << z;
	for (const auto& s : S)
	  std::cout << std::setw(width) << s(z);
	std::cout << '\n';
      }

    auto __nu = _Tp{20};
    const auto _S_2p13 = _Tp{1.259921049894873164767210607278228350570Q};
    const auto _S_2p23 = _Tp{1.587401051968199474751705639272308260393Q};
    const auto _S_2p43 = _Tp{2.519842099789746329534421214556456701140Q};
    const auto _S_2p53 = _Tp{3.174802103936398949503411278544616520785Q};
    const auto _S_pi   = _Tp{3.141592653589793238462643383279502884195Q};
    const auto __nu13 = std::pow(__nu, _Tp{1} / _Tp{3});
    const auto __nu23 = __nu13 * __nu13;
    const auto __nu43 = __nu23 * __nu23;

    std::cout << "\n\nTransition region Bessel functions: J_\\nu(\\nu + a\\nu^{1/3})\n";
    std::cout << "\nnu = " << __nu << "\n"
	      << std::setw(width) << "a"
	      << std::setw(width) << "J_\\nu"
	      << std::setw(width) << "N_\\nu"
	      << std::setw(width) << "J'_\\nu"
	      << std::setw(width) << "N'_\\nu"
	      << '\n';
    for (int __i = -100; __i <= +100; ++__i)
      {
	auto __a = _Tp{0.005Q} * __i;
	const auto __airy_arg = -_S_2p13 * __a;
	_Tp _Ai, _Bi, _Aip, _Bip;
	std::__detail::__airy(__airy_arg, _Ai, _Bi, _Aip, _Bip);

	auto __num2k3 = _Tp{1};

	auto _Jsum1 = _Tp{0};
	auto _Nsum1 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __p : P)
	  {
	    _Jsum1 += __p(__a) * __num2k3;
	    _Nsum1 += __p(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	auto _Jsum2 = _Tp{0};
	auto _Nsum2 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __q : Q)
	  {
	    _Jsum2 += __q(__a) * __num2k3;
	    _Nsum2 += __q(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	const auto _Jt = _S_2p13 * _Ai * _Jsum1 / __nu13
		       + _S_2p23 * _Aip * _Jsum2 / __nu;
	const auto _Nt = -_S_2p13 * _Bi * _Nsum1 / __nu13
			- _S_2p23 * _Bip * _Nsum2 / __nu;

	auto _Jpsum1 = _Tp{0};
	auto _Npsum1 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __r : R)
	  {
	    _Jpsum1 += __r(__a) * __num2k3;
	    _Npsum1 += __r(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	auto _Jpsum2 = _Tp{0};
	auto _Npsum2 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __s : S)
	  {
	    _Jpsum2 += __s(__a) * __num2k3;
	    _Npsum2 += __s(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	const auto _Jtp = -_S_2p23 * _Aip * _Jpsum1 / __nu23
			 + _S_2p13 * _Ai * _Jpsum2 / __nu43;
	const auto _Ntp = _S_2p23 * _Bip * _Npsum1 / __nu23
			- _S_2p13 * _Bi * _Npsum2 / __nu43;

	std::cout << std::setw(width) << __a
		  << std::setw(width) << _Jt
		  << std::setw(width) << _Nt
		  << std::setw(width) << _Jtp
		  << std::setw(width) << _Ntp
		  << std::setw(width) << '\n';
      }

    const auto __mipi3 = std::polar(-_S_pi / _Tp{3});
    const auto __pipi3 = std::polar(+_S_pi / _Tp{3});
    std::cout << "\n\nTransition region Bessel functions: J_\\nu(\\nu + a\\nu^{1/3})\n";
    std::cout << "\nnu = " << __nu << "\n"
	      << std::setw(2*width) << "a"
	      << std::setw(2*width) << "J_\\nu"
	      << std::setw(2*width) << "N_\\nu"
	      << std::setw(2*width) << "J'_\\nu"
	      << std::setw(2*width) << "N'_\\nu"
	      << '\n';

    const auto __eps = std::numeric_limits<_Tp>::epsilon();
    for (int __i = -100; __i <= +100; ++__i)
      {
	auto __a = _Tp{0.005Q} * __i;

	const std::complex<_Tp> __airy_argm = _S_2p13 * __a * __mipi3;
	std::complex<_Tp> _Ami, _Bmi, _Amip, _Bmip;
	std::__detail::__airy(__airy_argm, __eps, _Ami, _Bmi, _Amip, _Bmip);

	const std::complex<_Tp> __airy_argp = _S_2p13 * __a * __pipi3;
	std::complex<_Tp> _Api, _Bpi, _Apip, _Bpip;
	std::__detail::__airy(__airy_argp, __eps, _Api, _Bpi, _Apip, _Bpip);

	auto __num2k3 = _Tp{1};

	auto _H1sum1 = _Tp{0};
	auto _H2sum1 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __p : P)
	  {
	    _H1sum1 += __p(__a) * __num2k3;
	    _H2sum1 += __p(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	auto _H1sum2 = _Tp{0};
	auto _H2sum2 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __q : Q)
	  {
	    _H1sum2 += __q(__a) * __num2k3;
	    _H2sum2 += __q(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	const auto _H1t = _S_2p43 * __mipi3 * _Ami * _H1sum1 / __nu13
			+ _S_2p53 * __mipi3 * _Amip * _H1sum2 / __nu;
	const auto _H2t = _S_2p43 * __pipi3 * _Api * _H2sum1 / __nu13
			+ _S_2p53 * __pipi3 * _Apip * _H2sum2 / __nu;

	auto _H1psum1 = _Tp{0};
	auto _H2psum1 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __r : R)
	  {
	    _H1psum1 += __r(__a) * __num2k3;
	    _H2psum1 += __r(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	auto _H1psum2 = _Tp{0};
	auto _H2psum2 = _Tp{0};
	__num2k3 = _Tp{1};
	for (const auto& __s : S)
	  {
	    _H1psum2 += __s(__a) * __num2k3;
	    _H2psum2 += __s(__a) * __num2k3;
	    __num2k3 /= __nu23;
	  }

	const auto _H1pt = -_S_2p53 * __mipi3 * _Amip * _H1psum1 / __nu23
			  + _S_2p43 * __mipi3 * _Ami * _H1psum2 / __nu43;
	const auto _H2pt = -_S_2p53 * __pipi3 * _Apip * _H2psum1 / __nu23
			  + _S_2p43 * __pipi3 * _Api * _H2psum2 / __nu43;

	std::cout << std::setw(2*width) << __a
		  << std::setw(2*width) << _H1t
		  << std::setw(2*width) << _H2t
		  << std::setw(2*width) << _H1pt
		  << std::setw(2*width) << _H2pt
		  << std::setw(2*width) << '\n';
      }
  }
	double X = lua_tonumber(L, 1); \
	double Y = lua_tonumber(L, 2); \
	double Z = lua_tonumber(L, 3); \
 \
	double s[3]; \
	for(int j=0; j<3; j++) \
	{ \
		lua_pushinteger(L, 1+j); \
		lua_gettable(L, 4); \
		s[j] = lua_tonumber(L, -1); \
		lua_pop(L, 1); \
	} \
	lua_pushnumber(L, F(X, Y, Z, s)); \
	return 1; \
	
static int l_pxx(lua_State* L){ __p(magnetostatic_Pxx) }
static int l_pxy(lua_State* L){ __p(magnetostatic_Pxy) }
static int l_pxz(lua_State* L){ __p(magnetostatic_Pxz) }

static int l_pyx(lua_State* L){ __p(magnetostatic_Pyx) }
static int l_pyy(lua_State* L){ __p(magnetostatic_Pyy) }
static int l_pyz(lua_State* L){ __p(magnetostatic_Pyz) }

static int l_pzx(lua_State* L){ __p(magnetostatic_Pzx) }
static int l_pzy(lua_State* L){ __p(magnetostatic_Pzy) }
static int l_pzz(lua_State* L){ __p(magnetostatic_Pzz) }

MAGNETOSTATICS2D_API int lib_register(lua_State* L)
{
	luaT_register<Magnetostatics2D>(L);