https://github.com/epiqc/ScaffCC
Tip revision: fb0341d7eb6d3ae899a20f913e9f550f738d1bea authored by ah744 on 22 December 2016, 07:02:43 UTC
afree patch
afree patch
Tip revision: fb0341d
numbersgen.cpp
// Copyright (c) 2012 Vadym Kliuchnikov sqct(dot)software(at)gmail(dot)com, Dmitri Maslov, Michele Mosca
//
// This file is part of SQCT.
//
// SQCT 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 3 of the License, or
// (at your option) any later version.
//
// SQCT 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 SQCT. If not, see <http://www.gnu.org/licenses/>.
//
#include "numbersgen.h"
#include <cassert>
static const int sde_not_computed = -1;
template< int de >
void numbersGenerator<de>::init()
{
int& first = sdes[0][0];
int& last = sdes[ip_range - 1][ipQ_range - 1];
std::fill(&first ,&last + 1,sde_not_computed);
}
template< int de >
bool numbersGenerator<de>::isInRange(int ipxx, int ipQxx) const
{
return ( ipxx >= 0 ) && ( ipxx < ip_range ) &&
( ( ipQxx + ipQ_offset ) >= 0 ) &&
( ( ipQxx + ipQ_offset ) < ipQ_range );
}
template< int de >
void numbersGenerator<de>::add_number( int a, int b , int c, int d, int ipxx )
{
int m1 = ( a == 0 ? 1 : 2 );
int m2 = ( b == 0 ? 1 : 2 );
int m3 = ( c == 0 ? 1 : 2 );
int m4 = ( d == 0 ? 1 : 2 );
static const int s[2] = {1,-1};
for ( int i1 = 0; i1 < m1 ; ++i1 )
for ( int i2 = 0; i2 < m2 ; ++i2 )
for ( int i3 = 0; i3 < m3 ; ++i3 )
for ( int i4 = 0; i4 < m4 ; ++i4 )
{
ri x( a * s[i1], b * s[i2], c * s[i3], d * s[i4]);
int ipQxx = x.ipQxx();
static const double SQRT2 =
1.4142135623730950488016887242096980785696718753769;
ri abs2x( ipxx, ipQxx, 0, -ipQxx );
auto res = abs2x.toComplex( 2 * denom_exp );
if( abs( res ) <= 1.0000001 )
{
if( sdes[ ipxx ][ ipQxx + ipQ_offset ] == sde_not_computed )
sdes[ ipxx ][ ipQxx + ipQ_offset ]
= sde( 2 * denom_exp, abs2x.gde() );
vals[ ipxx ][ ipQxx + ipQ_offset ].push_back( x );
m_total_numbers++;
}
}
}
template< int de >
void numbersGenerator<de>::generate_all_numbers()
{
for( int i1 = 0; i1 <= max_val; ++i1 )
{
int ipxx1 = i1 * i1;
for( int i2 = 0; i2 <= max_val; ++i2 )
{
int ipxx2 = ipxx1 + i2 * i2;
if( ipxx2 > max_val2 )
break;
for( int i3 = 0; i3 <= max_val; ++i3 )
{
int ipxx3 = ipxx2 + i3 * i3;
if( ipxx3 > max_val2 )
break;
for( int i4 = 0; i4 <= max_val; ++i4 )
{
int ipxx4 = ipxx3 + i4 * i4;
if( ipxx4 > max_val2 )
break;
add_number( i1, i2, i3, i4, ipxx4 );
}
}
}
}
}
template< int de >
numbersGenerator<de>::numbersGenerator() :
m_total_numbers(0)
{
assert( denom_exp % 2 == 0 );
init();
}
template< int de >
int numbersGenerator<de>::getSde(int ipxx, int ipQxx) const
{
assert( isInRange(ipxx,ipQxx) );
return sdes[ipxx][ipQ_offset + ipQxx];
}
template< int de >
const typename numbersGenerator<de>::riArray& numbersGenerator<de>::numbers(int ipxx, int ipQxx) const
{
assert( isInRange(ipxx,ipQxx) );
return vals[ipxx][ipQ_offset + ipQxx];
}
template< int de >
const typename numbersGenerator<de>::riArray& numbersGenerator<de>::numbersWithPair(int ipxx, int ipQxx) const
{
static const riArray emp;
const auto& res = numbers( max_val2 - ipxx,-ipQxx );
if( ! (res.empty() ) )
return vals[ipxx][ipQxx];
else
return emp;
}
//////// template compilation requests
template class numbersGenerator<2>;
template class numbersGenerator<4>;
template class numbersGenerator<6>;
template class numbersGenerator<8>;
template class numbersGenerator<10>;
template class numbersGenerator<12>;
//////////////////////////////////////
template< int de >
void columnsCounter<de>::count_all_columns()
{
sde_stat.resize(bs::max_sde,0);
for( int ipxx = 0; ipxx < bs::max_val2 + 1; ++ipxx )
{
for( int j = 0; j < bs::ipQ_range; ++j )
{
int ipyy = bs::max_val2 - ipxx;
int ipQxx = j - bs::ipQ_offset;
int ipQyy = -ipQxx;
int k = bs::ipQ_offset + ipQyy;
int sde = bs::sdes[ipxx][j];
int sde2 = bs::sdes[ipyy][k];
auto ii_end = bs::vals[ipxx][j].end();
for( auto ii = bs::vals[ipxx][j].begin(); ii != ii_end; ++ii )
{
auto jj_end = bs::vals[ipyy][k].end();
for( auto jj = bs::vals[ipyy][k].begin(); jj != jj_end; ++jj )
{
int idx =std::min(sde2,sde);
sde_stat[idx] ++;
}
}
}
}
}
//////// template compilation requests
template class columnsCounter<2>;
template class columnsCounter<4>;
template class columnsCounter<6>;
template class columnsCounter<8>;
template class columnsCounter<10>;
template class columnsCounter<12>;