88#include <vigra/multi_array.hxx>
89#include <vigra/accumulator.hxx>
90#include <vigra/multi_math.hxx>
101template <
typename T >
104 return std::abs ( t ) ;
107template <
typename T >
110 return sqrt ( sum ( t * t ) ) / t.size() ;
113template <
typename T >
114double condense (
const std::complex<T> & t , std::false_type )
116 return std::abs ( t ) ;
122 < std::is_fundamental < T > :: value ,
127template <
typename T >
135template <
int dim ,
typename T >
136double check_diff ( vigra::MultiArrayView < dim , T > & reference ,
137 vigra::MultiArrayView < dim , T > & candidate )
139 using namespace vigra::multi_math ;
140 using namespace vigra::acc;
142 assert ( reference.shape() == candidate.shape() ) ;
144 vigra::MultiArray < 1 , double >
145 error_array ( vigra::Shape1(reference.size() ) ) ;
147 for (
int i = 0 ; i < reference.size() ; i++ )
149 auto help = candidate[i] - reference[i] ;
152 error_array [ i ] =
condense ( help ) ;
155 AccumulatorChain < double , Select < Mean, Maximum > > ac ;
156 extractFeatures ( error_array.begin() , error_array.end() , ac ) ;
157 double mean = get<Mean>(ac) ;
158 double max = get<Maximum>(ac) ;
161 std::cout <<
"delta Mean: "
162 << mean << std::endl;
163 std::cout <<
"delta Maximum: "
186template <
int dim ,
typename T >
192 std::cout <<
"**************************************" << std::endl
193 <<
"testing type " <<
typeid(T()).name() << std::endl ;
195 typedef vigra::MultiArray < dim , T > array_type ;
197 vigra::TinyVector < vspline::bc_code , dim > bcv { bc } ;
199 spline_type bsp ( arr.shape() , spline_degree , bcv , 0.0 ) ;
202 std::cout <<
"created b-spline:" << std::endl << bsp << std::endl ;
204 std::random_device rd ;
205 std::mt19937 gen ( rd() ) ;
207 std::uniform_real_distribution<> dis ( -1.0 , 1.0 ) ;
208 for (
auto & e : arr )
210 array_type reference = arr ;
214 vspline::restore < dim , T > ( bsp , arr ) ;
217 std::cout <<
"after restoration of original data:" << std::endl ;
219 double emax = check_diff < dim , T > ( reference , arr ) ;
225 <<
typeid(T()).name()
228 <<
" " << arr.shape()
230 <<
" DG " << spline_degree
233 << emax << std::endl ;
250 spline_type polish ( arr.shape() , spline_degree , bcv , 0.0 ) ;
258 vspline::restore < dim , T > ( bsp , arr ) ;
261 std::cout <<
"after polishing of spline:" << std::endl ;
263 double emax2 = check_diff < dim , T > ( reference , arr ) ;
269 <<
typeid(T()).name()
272 <<
" " << arr.shape()
274 <<
" DG " << spline_degree
277 << emax2 << std::endl ;
285 typedef typename decltype ( raw_ev ) :: in_type fc_type ;
286 typedef typename decltype ( raw_ev ) :: in_nd_ele_type nd_fc_type ;
292 nd_fc_type & nd_cs (
reinterpret_cast < nd_fc_type &
> ( cs ) ) ;
294 auto rs = raw_ev ( cs ) ;
295 raw_ev.eval ( cs , rs ) ;
300 for (
int d = 0 ; d < dim ; d++ )
303 raw_ev.eval ( cs , rs ) ;
306 std::cout << cs <<
" -> " << rs << std::endl ;
308 for (
int d = 0 ; d < dim ; d++ )
311 raw_ev.eval ( cs , rs ) ;
314 std::cout << cs <<
" -> " << rs << std::endl ;
325 typedef typename decltype ( _ev ) :: in_ele_type
rc_type ;
326 typedef typename decltype ( _ev ) :: out_ele_type ele_type ;
340 vigra::MultiArray < 1 , coordinate_type > ca ( vigra::Shape1 ( 10003 ) ) ;
341 vigra::MultiArray < 1 , T > ra ( vigra::Shape1 ( 10003 ) ) ;
342 vigra::MultiArray < 1 , T > ra2 ( vigra::Shape1 ( 10003 ) ) ;
348 for (
int e = 0 ; e < dim ; e++ )
355 for (
int e = 0 ; e < dim ; e++ )
362 for (
int e = 0 ; e < dim ; e++ )
369 for (
int e = 2.0 ; e < dim ; e++ )
377 std::uniform_real_distribution<> dis2 ( -2.371 , 2.1113 ) ;
378 for ( k = 4 ; k < 10003 ; k++ )
380 for (
int e = 0 ; e < dim ; e++ )
381 pc[e] = dis2 ( gen ) ;
398 vigra::MultiArrayView < 2 , coordinate_type > ca2d
399 ( vigra::Shape2 ( 99 , 97 ) , ca.data() ) ;
400 vigra::MultiArrayView < 2 , T > ra2d
401 ( vigra::Shape2 ( 99 , 97 ) , ra2.data() ) ;
403 vigra::MultiArrayView < 2 , coordinate_type > ca2ds
404 ( vigra::Shape2 ( 49 , 49 ) , vigra::Shape2 ( 2 , 200 ) , ca.data() ) ;
405 vigra::MultiArrayView < 2 , T > ra2ds
406 ( vigra::Shape2 ( 49 , 49 ) , vigra::Shape2 ( 2 , 200 ) , ra2.data() ) ;
408 vigra::MultiArrayView < 3 , coordinate_type > ca3d
409 ( vigra::Shape3 ( 20 , 21 , 19 ) , ca.data() ) ;
410 vigra::MultiArrayView < 3 , T > ra3d
411 ( vigra::Shape3 ( 20 , 21 , 19 ) , ra2.data() ) ;
423 auto dsv = check_diff < 1 , T > ( ra , ra2 ) ;
424 auto tolerance = 10 * std::numeric_limits<ele_type>::epsilon() ;
426 if ( dsv > tolerance )
428 <<
" - max difference single/vectorized eval "
429 << dsv << std::endl ;
434 <<
" - excessive difference single/vectorized eval "
435 << dsv << std::endl ;
436 for (
int k = 0 ; k < 10003 ; k++ )
438 if ( ra[k] != ra2[k] )
440 std::cout <<
"excessive at k = " << k
441 <<
": " << ca[k] <<
" -> "
442 << ra[k] <<
", " << ra2[k] << std::endl ;
452template <
class arr_t >
457 enum { dimension = arr_t::actual_dimension } ;
458 typedef typename arr_t::value_type value_type ;
464 for (
int spline_degree = 0 ; spline_degree < 8 ; spline_degree++ )
466 for (
auto bc : bc_seq )
468 auto e = restore_test < dimension , value_type >
469 ( arr , bc , spline_degree ) ;
477int d0[] { 1 , 2 , 3 , 5 , 8 , 13 , 16 , 21 ,
478 34 , 55 , 123 , 128 , 289 , 500 , 1031 ,
480int d1[] { 1 , 2 , 3 , 5 , 8 , 13 , 16 , 21 ,
481 34 , 89 , 160 , 713 } ;
482int d2[] { 2 , 3 , 5 , 8 , 13 , 21 } ;
483int d3[] { 2 , 3 , 5 , 8 , 13 } ;
486int dsz[] {
sizeof(
d0) /
sizeof(
int) ,
487 sizeof(
d1) /
sizeof(
int) ,
488 sizeof(
d2) /
sizeof(
int) ,
489 sizeof(
d3) /
sizeof(
int) } ;
491template <
int dim ,
typename T >
500 for (
int d = 0 ; d < dim ; d++ )
503 vigra::MultiCoordinateIterator<dim> i ( dshape ) ,
504 end = i.getEndIterator() ;
509 for (
int d = 0 ; d < dim ; d++ )
510 shape[d] = * (
dext[d] + (*i)[d] ) ;
512 vigra::MultiArray < dim , T > _arr ( 2 * shape + 1 ) ;
513 auto stride = _arr.stride() * 2 ;
514 vigra::MultiArrayView < dim , T >
515 arr ( shape , stride , _arr.data() + long ( sum ( stride ) ) ) ;
523 for (
auto & e : arr )
525 for (
auto e : _arr )
526 assert ( e == T(0.0) ) ;
532template <
typename T >
542 typename tuple_type ,
543 int ntypes = std::tuple_size<tuple_type>::value >
548 typedef typename std::tuple_element<ntypes-1,tuple_type>::type T ;
550 std::cout <<
"test for type " <<
typeid(T()).name()
551 <<
": max error = " << e << std::endl ;
552 multitest < dim , tuple_type , ntypes - 1 >() () ;
557 typename tuple_type >
565int main (
int argc ,
char * argv[] )
567 std::cout << std::fixed << std::showpos << std::showpoint
568 << std::setprecision(18);
569 std::cerr << std::fixed << std::showpos << std::showpoint
570 << std::setprecision(18);
574 test_dim = std::atoi ( argv[1] ) ;
578 std::cout <<
"testing with " << test_dim <<
" dimensions" << std::endl ;
581 vigra::TinyVector < double , 1 > ,
582 vigra::TinyVector < float , 1 > ,
583 vigra::TinyVector < double , 2 > ,
584 vigra::TinyVector < float , 2 > ,
585 vigra::TinyVector < long double , 3 > ,
586 vigra::TinyVector < double , 3 > ,
587 vigra::TinyVector < float , 3 > ,
588 vigra::RGBValue<long double> ,
589 vigra::RGBValue<double> ,
590 vigra::RGBValue<float,0,1,2> ,
591 std::complex < long double > ,
592 std::complex < double > ,
593 std::complex < float > ,
616 std::cout <<
"terminating" << std::endl ;
vigra::TinyVector< float, 2 > coordinate_type
vspline::bspline< pixel_type, 2 > spline_type
typename std::conditional< std::is_fundamental< T > ::value, std::true_type, std::false_type > ::type is_singular
vspline::domain_type< coordinate_type, _vsize > domain(const coordinate_type &in_low, const coordinate_type &in_high, const coordinate_type &out_low, const coordinate_type &out_high)
factory function to create a domain_type type object from the desired lower and upper fix point for i...
void transform(const unary_functor_type &functor, const vigra::MultiArrayView< dimension, typename unary_functor_type::in_type > &input, vigra::MultiArrayView< dimension, typename unary_functor_type::out_type > &output, int njobs=vspline::default_njobs, vspline::atomic< bool > *p_cancel=0)
implementation of two-array transform using wielding::coupled_wield.
vspline::grok_type< typename grokkee_type::in_type, typename grokkee_type::out_type, grokkee_type::vsize > grok(const grokkee_type &grokkee)
grok() is the corresponding factory function, wrapping grokkee in a vspline::grok_type.
vspline::grok_type< bspl_coordinate_type< spline_type, rc_type >, result_type, _vsize > make_evaluator(const spline_type &bspl, vigra::TinyVector< int, spline_type::dimension > dspec=vigra::TinyVector< int, spline_type::dimension >(0), int shift=0)
make_evaluator is a factory function, producing a functor which provides access to an evaluator objec...
const std::string bc_name[]
bc_name is for diagnostic output of bc codes
vspline::grok_type< bspl_coordinate_type< spline_type, rc_type >, result_type, _vsize > make_safe_evaluator(const spline_type &bspl, vigra::TinyVector< int, spline_type::dimension > dspec=vigra::TinyVector< int, spline_type::dimension >(0), int shift=0)
make_safe_evaluator is a factory function, producing a functor which provides safe access to an evalu...
bc_code
This enumeration is used for codes connected to boundary conditions. There are two aspects to boundar...
int main(int argc, char *argv[])
double restore_test(vigra::MultiArrayView< dim, T > &arr, vspline::bc_code bc, int spline_degree)
do a restore test. This test fills the array that's passed in with small random data,...
double view_test(arr_t &arr)
bool verbose
restore_test - create b-splines from random data and restore the original data from the spline....
double condense(const T &t, std::true_type)
double check_diff(vigra::MultiArrayView< dim, T > &reference, vigra::MultiArrayView< dim, T > &candidate)
vigra::TinyVector< int, dim > shape_type
class bspline now builds on class bspline_base, adding coefficient storage, while bspline_base provid...
void prefilter(vspline::xlf_type boost=vspline::xlf_type(1), int njobs=vspline::default_njobs)
prefilter converts the knot point data in the 'core' area into b-spline coefficients....
void brace(int axis=-1)
if the spline coefficients are already known, they obviously don't need to be prefiltered....
static xlf_type lower_limit(const bc_code &bc)
lower_limit returns the lower bound of the spline's defined range. This is usually 0....
static xlf_type upper_limit(const std::size_t &extent, const bc_code &bc)
upper_limit returns the upper bound of the spline's defined range. This is normally M - 1 if the shap...
includes all headers from vspline (most of them indirectly)